From f15089cf40fc434b7869c536f2f7d394258fb7b3 Mon Sep 17 00:00:00 2001 From: "M.-Leander Reimer" Date: Thu, 5 Dec 2024 11:02:37 +0100 Subject: [PATCH] Added external secrets configuration and docs. --- .gitignore | 2 +- Makefile | 11 +++++++++++ README.md | 16 ++++++++++++++++ .../external-secrets/kustomization.yaml | 4 +++- .../platform/external-secrets/sa-secret.yaml | 18 ++++++++++++++++++ .../platform/external-secrets/sa.yaml | 7 +++++++ .../external-secrets/secret-store.yaml | 18 ++++++++++++++++++ 7 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 infrastructure/platform/external-secrets/sa-secret.yaml create mode 100644 infrastructure/platform/external-secrets/sa.yaml create mode 100644 infrastructure/platform/external-secrets/secret-store.yaml diff --git a/.gitignore b/.gitignore index 075df3c..6af3a3c 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,4 @@ gradle-app.setting .vscode/ .DS_Store target/ -airbyte.json \ No newline at end of file +*.json \ No newline at end of file diff --git a/Makefile b/Makefile index 35fb564..647be49 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ bootstrap-flux2: --read-write-key \ --personal +# Create a Service Account for Airbyte storage and secrets create-gke-airbyte-sa: @gcloud iam service-accounts create airbyte --description="Airbyte Service Account" --display-name="Airbyte Service Account" @gcloud projects add-iam-policy-binding $(GCP_PROJECT) --role=roles/storage.admin --member=serviceAccount:airbyte@$(GCP_PROJECT).iam.gserviceaccount.com @@ -45,5 +46,15 @@ create-gke-airbyte-sa: @gcloud projects add-iam-policy-binding $(GCP_PROJECT) --role=roles/secretmanager.viewer --member=serviceAccount:airbyte@$(GCP_PROJECT).iam.gserviceaccount.com @gcloud iam service-accounts keys create airbyte.json --iam-account=airbyte@$(GCP_PROJECT).iam.gserviceaccount.com +# Create a Service Account for External Secrets +create-gke-es-sa: + @gcloud iam service-accounts create external-secrets-sa --description="External Secrets Service Account" --display-name="External Secrets Service Account" + @gcloud projects add-iam-policy-binding $(GCP_PROJECT) --role=roles/secretmanager.secretAccessor --member=serviceAccount:external-secrets-sa@$(GCP_PROJECT).iam.gserviceaccount.com + @gcloud projects add-iam-policy-binding $(GCP_PROJECT) --role=roles/secretmanager.secretVersionAdder --member=serviceAccount:external-secrets-sa@$(GCP_PROJECT).iam.gserviceaccount.com + @gcloud projects add-iam-policy-binding $(GCP_PROJECT) --role=roles/secretmanager.secretVersionManager --member=serviceAccount:external-secrets-sa@$(GCP_PROJECT).iam.gserviceaccount.com + @gcloud projects add-iam-policy-binding $(GCP_PROJECT) --role=roles/secretmanager.viewer --member=serviceAccount:external-secrets-sa@$(GCP_PROJECT).iam.gserviceaccount.com + @gcloud projects add-iam-policy-binding $(GCP_PROJECT) --role=roles/iam.serviceAccountTokenCreator --member=serviceAccount:external-secrets-sa@$(GCP_PROJECT).iam.gserviceaccount.com + @gcloud iam service-accounts keys create external-secrets-sa.json --iam-account=external-secrets-sa@$(GCP_PROJECT).iam.gserviceaccount.com + delete-gke-clusters: @gcloud container clusters delete k8s-native-java-ai --region=$(GCP_REGION) --async --quiet diff --git a/README.md b/README.md index 2a7b69c..43f6723 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,22 @@ make bootstrap-flux2 kubectl annotate namespace default cnrm.cloud.google.com/project-id="cloud-native-experience-lab" ``` +## External Secrets using Google Cloud Security Manager + +```bash +# credentials to access certain GCP infrastructure components are stored externally +# make sure that the Google Cloud Security Manager API is enabled in your project +make create-gke-es-sa + +# if required change and apply the ClusterSecretStore CRD +kubectl apply -f infrastructure/platform/external-secrets/secret-store.yaml + +# this is how to create secrets in the +gcloud secrets create external-secrets-sa --data-file=external-secrets-sa.json --replication-policy=automatic +kubectl apply -f infrastructure/platform/external-secrets/sa-secret.yaml +kubectl get secret gcp-sa-credentials -o jsonpath='{.data.external-secrets-sa.json}' | base64 -d +``` + ## Building a chat service with Quarkus and OpenAI ```bash diff --git a/infrastructure/platform/external-secrets/kustomization.yaml b/infrastructure/platform/external-secrets/kustomization.yaml index 1658c0f..4c09e63 100644 --- a/infrastructure/platform/external-secrets/kustomization.yaml +++ b/infrastructure/platform/external-secrets/kustomization.yaml @@ -2,5 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - namespace.yaml + - sa.yaml - repository.yaml - - release.yaml \ No newline at end of file + - release.yaml + - secret-store.yaml \ No newline at end of file diff --git a/infrastructure/platform/external-secrets/sa-secret.yaml b/infrastructure/platform/external-secrets/sa-secret.yaml new file mode 100644 index 0000000..c73dd39 --- /dev/null +++ b/infrastructure/platform/external-secrets/sa-secret.yaml @@ -0,0 +1,18 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gcp-sa-credentials + namespace: default +spec: + refreshInterval: 1h # rate SecretManager pulls GCPSM + secretStoreRef: + kind: ClusterSecretStore + name: gcp-secret-manager-store # name of the SecretStore (or kind specified) + namespace: external-secrets + target: + name: gcp-sa-credentials # name of the k8s Secret to be created + creationPolicy: Owner + data: + - secretKey: external-secrets-sa.json + remoteRef: + key: external-secrets-sa # name of the GCPSM secret key diff --git a/infrastructure/platform/external-secrets/sa.yaml b/infrastructure/platform/external-secrets/sa.yaml new file mode 100644 index 0000000..847f997 --- /dev/null +++ b/infrastructure/platform/external-secrets/sa.yaml @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: external-secrets-sa + namespace: external-secrets + annotations: + iam.gke.io/gcp-service-account: external-secrets-sa@cloud-native-experience-lab.iam.gserviceaccount.com diff --git a/infrastructure/platform/external-secrets/secret-store.yaml b/infrastructure/platform/external-secrets/secret-store.yaml new file mode 100644 index 0000000..c62a831 --- /dev/null +++ b/infrastructure/platform/external-secrets/secret-store.yaml @@ -0,0 +1,18 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ClusterSecretStore +metadata: + name: gcp-secret-manager-store + namespace: external-secrets +spec: + provider: + gcpsm: + projectID: cloud-native-experience-lab + auth: + workloadIdentity: + clusterLocation: europe-west4 + clusterName: k8s-native-java-ai + # projectID of the cluster (if omitted defaults to spec.provider.gcpsm.projectID) + # clusterProjectID: cloud-native-experience-lab + serviceAccountRef: + name: external-secrets-sa + namespace: external-secrets \ No newline at end of file