diff --git a/bin/update.sh b/bin/update.sh index 7a6088d..182b12a 100755 --- a/bin/update.sh +++ b/bin/update.sh @@ -56,5 +56,21 @@ rm -fr files/digitalocean.old generated.log csi-digitalocean-latest.yaml #https://github.com/wavezhang/k8s-csi-lvm ? #https://github.com/juicedata/juicefs-csi-driver ? + +SECRETS_STORE_FILE=vars/secrets_store_files_list.yml +echo -e "---\nsecrets_store_files:" > "${SECRETS_STORE_FILE}" +git clone https://github.com/kubernetes-sigs/secrets-store-csi-driver.git +kubernetes-split-yaml secrets-store-csi-driver/deploy/rbac-secretproviderclass.yaml > generated.log +kubernetes-split-yaml secrets-store-csi-driver/deploy/csidriver.yaml >> generated.log +kubernetes-split-yaml secrets-store-csi-driver/deploy/secrets-store.csi.x-k8s.io_secretproviderclasses.yaml >> generated.log +kubernetes-split-yaml secrets-store-csi-driver/deploy/secrets-store-csi-driver.yaml >> generated.log +cat generated.log | while read LIGNE; do if [ $(echo "${LIGNE}" | grep -c ^File) -eq 1 ]; then echo -n "${LIGNE} "; else echo "${LIGNE}"; fi; done | grep ^File | sed 's|.*\(generated/\)\(.*\.yaml\)| - "secrets-store/\2"|' >> "${SECRETS_STORE_FILE}" +mv files/secrets-store{,.old} +mv generated files/secrets-store +sed "/^metadata:$/a \ namespace: csi-secrets-store" -i files/secrets-store/csi-secrets-store-DaemonSet.yaml +rm -fr files/secrets-store.old generated.log secrets-store-csi-driver +curl -s -o files/secrets-store/provider-vault-installer.yaml https://raw.githubusercontent.com/hashicorp/secrets-store-csi-driver-provider-vault/master/deployment/provider-vault-installer.yaml +sed "/^metadata:$/a \ namespace: csi-secrets-store" -i files/secrets-store/provider-vault-installer.yaml +echo ' - "secrets-store/provider-vault-installer.yaml"' >> "${SECRETS_STORE_FILE}" #https://github.com/Azure/secrets-store-csi-driver-provider-azure #https://github.com/hashicorp/secrets-store-csi-driver-provider-vault diff --git a/defaults/main.yml b/defaults/main.yml index 835eec3..9041aa0 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -2,6 +2,7 @@ my_context: minikube storage_localpath: true storage_linode: false storage_digitalocean: false +storage_secrets_store: false # local-path, linode-block-storage, linode-block-storage-retain, do-block-storage storage_default_storageclass: local-path \ No newline at end of file diff --git a/files/secrets-store/csi-secrets-store-DaemonSet.yaml b/files/secrets-store/csi-secrets-store-DaemonSet.yaml new file mode 100644 index 0000000..e88104e --- /dev/null +++ b/files/secrets-store/csi-secrets-store-DaemonSet.yaml @@ -0,0 +1,111 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + namespace: csi-secrets-store + name: csi-secrets-store +spec: + selector: + matchLabels: + app: csi-secrets-store + template: + metadata: + labels: + app: csi-secrets-store + spec: + nodeSelector: + beta.kubernetes.io/os: linux + serviceAccountName: secrets-store-csi-driver + hostNetwork: true + containers: + - name: node-driver-registrar + image: quay.io/k8scsi/csi-node-driver-registrar:v1.2.0 + args: + - --v=5 + - --csi-address=/csi/csi.sock + - --kubelet-registration-path=/var/lib/kubelet/plugins/csi-secrets-store/csi.sock + lifecycle: + preStop: + exec: + command: + [ + "/bin/sh", + "-c", + "rm -rf /registration/secrets-store.csi.k8s.io-reg.sock", + ] + env: + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + imagePullPolicy: Always + volumeMounts: + - name: plugin-dir + mountPath: /csi + - name: registration-dir + mountPath: /registration + - name: secrets-store + image: docker.io/deislabs/secrets-store-csi:v0.0.11 + args: + - "--debug=true" + - "--endpoint=$(CSI_ENDPOINT)" + - "--nodeid=$(KUBE_NODE_NAME)" + - "--provider-volume=/etc/kubernetes/secrets-store-csi-providers" + env: + - name: CSI_ENDPOINT + value: unix:///csi/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + imagePullPolicy: Always + securityContext: + privileged: true + ports: + - containerPort: 9808 + name: healthz + protocol: TCP + livenessProbe: + failureThreshold: 5 + httpGet: + path: /healthz + port: healthz + initialDelaySeconds: 30 + timeoutSeconds: 10 + periodSeconds: 15 + volumeMounts: + - name: plugin-dir + mountPath: /csi + - name: mountpoint-dir + mountPath: /var/lib/kubelet/pods + mountPropagation: Bidirectional + - name: providers-dir + mountPath: /etc/kubernetes/secrets-store-csi-providers + - name: liveness-probe + image: quay.io/k8scsi/livenessprobe:v1.1.0 + imagePullPolicy: Always + args: + - --csi-address=/csi/csi.sock + - --probe-timeout=3s + - --health-port=9808 + volumeMounts: + - name: plugin-dir + mountPath: /csi + volumes: + - name: mountpoint-dir + hostPath: + path: /var/lib/kubelet/pods + type: DirectoryOrCreate + - name: registration-dir + hostPath: + path: /var/lib/kubelet/plugins_registry/ + type: Directory + - name: plugin-dir + hostPath: + path: /var/lib/kubelet/plugins/csi-secrets-store/ + type: DirectoryOrCreate + - name: providers-dir + hostPath: + path: /etc/kubernetes/secrets-store-csi-providers + type: DirectoryOrCreate diff --git a/files/secrets-store/provider-vault-installer.yaml b/files/secrets-store/provider-vault-installer.yaml new file mode 100644 index 0000000..3f2b17d --- /dev/null +++ b/files/secrets-store/provider-vault-installer.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + namespace: csi-secrets-store + labels: + app: csi-secrets-store-provider-vault + name: csi-secrets-store-provider-vault +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + app: csi-secrets-store-provider-vault + template: + metadata: + labels: + app: csi-secrets-store-provider-vault + spec: + tolerations: + containers: + - name: provider-vault-installer + image: hashicorp/secrets-store-csi-driver-provider-vault:0.0.4 + imagePullPolicy: Always + resources: + requests: + cpu: 50m + memory: 100Mi + limits: + cpu: 50m + memory: 100Mi + env: + # set TARGET_DIR env var and mount the same directory to to the container + - name: TARGET_DIR + value: "/etc/kubernetes/secrets-store-csi-providers" + volumeMounts: + - mountPath: "/etc/kubernetes/secrets-store-csi-providers" + name: providervol + volumes: + - name: providervol + hostPath: + path: "/etc/kubernetes/secrets-store-csi-providers" + nodeSelector: + beta.kubernetes.io/os: linux diff --git a/files/secrets-store/secretproviderclasses-role-ClusterRole.yaml b/files/secrets-store/secretproviderclasses-role-ClusterRole.yaml new file mode 100644 index 0000000..093e607 --- /dev/null +++ b/files/secrets-store/secretproviderclasses-role-ClusterRole.yaml @@ -0,0 +1,30 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: secretproviderclasses-role +rules: +- apiGroups: + - secrets-store.csi.x-k8s.io + resources: + - secretproviderclasses + verbs: + - get + - list + - update +- apiGroups: + - secrets-store.csi.x-k8s.io + resources: + - secretproviderclasses/status + verbs: + - get + - patch + - update +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - update diff --git a/files/secrets-store/secretproviderclasses-rolebinding-ClusterRoleBinding.yaml b/files/secrets-store/secretproviderclasses-rolebinding-ClusterRoleBinding.yaml new file mode 100644 index 0000000..afce2ea --- /dev/null +++ b/files/secrets-store/secretproviderclasses-rolebinding-ClusterRoleBinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: secretproviderclasses-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: secretproviderclasses-role +subjects: +- kind: ServiceAccount + name: secrets-store-csi-driver + namespace: default diff --git a/files/secrets-store/secretproviderclasses.secrets-store.csi.x-k8s.io-CustomResourceDefinition.yaml b/files/secrets-store/secretproviderclasses.secrets-store.csi.x-k8s.io-CustomResourceDefinition.yaml new file mode 100644 index 0000000..117a6b7 --- /dev/null +++ b/files/secrets-store/secretproviderclasses.secrets-store.csi.x-k8s.io-CustomResourceDefinition.yaml @@ -0,0 +1,99 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.2.4 + creationTimestamp: null + name: secretproviderclasses.secrets-store.csi.x-k8s.io +spec: + group: secrets-store.csi.x-k8s.io + names: + kind: SecretProviderClass + listKind: SecretProviderClassList + plural: secretproviderclasses + singular: secretproviderclass + scope: Namespaced + validation: + openAPIV3Schema: + description: SecretProviderClass is the Schema for the secretproviderclasses + API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: SecretProviderClassSpec defines the desired state of SecretProviderClass + properties: + parameters: + additionalProperties: + type: string + description: Configuration for specific provider + type: object + provider: + description: Configuration for provider name + type: string + secretObjects: + items: + description: SecretObject defines the desired state of synced K8s + secret objects + properties: + data: + items: + description: SecretObjectData defines the desired state of synced + K8s secret object data + properties: + key: + description: data field to populate + type: string + objectName: + description: name of the object to sync + type: string + type: object + type: array + secretName: + description: name of the K8s secret object + type: string + type: + description: type of K8s secret object + type: string + type: object + type: array + type: object + status: + description: SecretProviderClassStatus defines the observed state of SecretProviderClass + properties: + byPod: + items: + description: ByPodStatus defines the state of SecretProviderClass + as seen by an individual controller + properties: + id: + description: id of the pod that wrote the status + type: string + namespace: + description: namespace of the pod that wrote the status + type: string + type: object + type: array + type: object + type: object + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/files/secrets-store/secrets-store-csi-driver-ServiceAccount.yaml b/files/secrets-store/secrets-store-csi-driver-ServiceAccount.yaml new file mode 100644 index 0000000..e98e48a --- /dev/null +++ b/files/secrets-store/secrets-store-csi-driver-ServiceAccount.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: secrets-store-csi-driver + namespace: default diff --git a/files/secrets-store/secrets-store.csi.k8s.io-CSIDriver.yaml b/files/secrets-store/secrets-store.csi.k8s.io-CSIDriver.yaml new file mode 100644 index 0000000..a04e928 --- /dev/null +++ b/files/secrets-store/secrets-store.csi.k8s.io-CSIDriver.yaml @@ -0,0 +1,9 @@ +apiVersion: storage.k8s.io/v1beta1 +kind: CSIDriver +metadata: + name: secrets-store.csi.k8s.io +spec: + podInfoOnMount: true + attachRequired: false + volumeLifecycleModes: + - Ephemeral diff --git a/tasks/main.yml b/tasks/main.yml index 5249cff..b6c20f6 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -3,6 +3,7 @@ - include_tasks: "local.yml" - include_tasks: "digital_ocean.yml" - include_tasks: "linode.yml" + - include_tasks: "secrets-store.yml" - name: Select the default StorageClass k8s: diff --git a/tasks/secrets-store.yml b/tasks/secrets-store.yml new file mode 100644 index 0000000..daca61b --- /dev/null +++ b/tasks/secrets-store.yml @@ -0,0 +1,21 @@ +--- + - name: Defined secrets-storage state to present + set_fact: + storage_secrets_store_state: present + when: + - storage_secrets_store|bool + + - name: find state of secrets-storage + set_fact: + storage_secrets_store_state: absent + when: + - not storage_secrets_store|bool + + - name: secrets-storage need to be {{ storage_secrets_store_state }} + k8s: + state: "{{ storage_secrets_store_state }}" + context: "{{ my_context }}" + merge_type: merge + resource_definition: "{{ lookup('file', item) | from_yaml }}" + with_items: + - '{{ secrets_store_files }}' diff --git a/vars/secrets_store_files_list.yml b/vars/secrets_store_files_list.yml new file mode 100644 index 0000000..fcdd787 --- /dev/null +++ b/vars/secrets_store_files_list.yml @@ -0,0 +1,9 @@ +--- +secrets_store_files: + - "secrets-store/secrets-store-csi-driver-ServiceAccount.yaml" + - "secrets-store/secretproviderclasses-rolebinding-ClusterRoleBinding.yaml" + - "secrets-store/secretproviderclasses-role-ClusterRole.yaml" + - "secrets-store/secrets-store.csi.k8s.io-CSIDriver.yaml" + - "secrets-store/secretproviderclasses.secrets-store.csi.x-k8s.io-CustomResourceDefinition.yaml" + - "secrets-store/csi-secrets-store-DaemonSet.yaml" + - "secrets-store/provider-vault-installer.yaml"