From f0c163c530432168edf3fed05747aade0cfc4c53 Mon Sep 17 00:00:00 2001 From: saladgg Date: Mon, 15 Jan 2024 13:06:04 +0300 Subject: [PATCH] refactor: add service account --- cloudbuild.yaml | 41 ++++++- deploy/README.md | 1 + deploy/ReadMe.md | 0 .../01_common/01_service_account.yaml | 9 ++ .../01_dbuser_configmap.yml} | 1 + .../02_db_configmap.yml} | 1 + .../03_pgb_configmap.yml} | 1 + .../04_deployment.yaml} | 8 +- .../05_service.yaml} | 2 +- .../templates/03_django/01_confimap_job.yml | 104 ++++++++++++++++++ .../02_deployment.yml} | 4 +- .../03_service.yaml} | 2 +- .../01_ingress.yaml} | 2 +- .../02_cert_issuer.yaml} | 2 +- deploy/values.yaml | 15 ++- 15 files changed, 179 insertions(+), 14 deletions(-) create mode 100644 deploy/README.md delete mode 100644 deploy/ReadMe.md create mode 100644 deploy/templates/01_common/01_service_account.yaml rename deploy/templates/{pg-bouncer/dbuser_configmap.yml => 02_pg_bouncer/01_dbuser_configmap.yml} (84%) rename deploy/templates/{pg-bouncer/db_configmap.yml => 02_pg_bouncer/02_db_configmap.yml} (88%) rename deploy/templates/{pg-bouncer/pgb_configmap.yml => 02_pg_bouncer/03_pgb_configmap.yml} (92%) rename deploy/templates/{pg-bouncer/deployment.yaml => 02_pg_bouncer/04_deployment.yaml} (84%) rename deploy/templates/{pg-bouncer/service.yaml => 02_pg_bouncer/05_service.yaml} (90%) create mode 100644 deploy/templates/03_django/01_confimap_job.yml rename deploy/templates/{django/deployment.yaml => 03_django/02_deployment.yml} (88%) rename deploy/templates/{django/service.yaml => 03_django/03_service.yaml} (88%) rename deploy/templates/{ingress/ingress.yaml => 04_ingress/01_ingress.yaml} (94%) rename deploy/templates/{ingress/cert_issuer.yaml => 04_ingress/02_cert_issuer.yaml} (91%) diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 68a055a..75dd9c9 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -95,12 +95,26 @@ steps: - --values - values.yaml - --set - - namespace=${_NAMESPACE} + - common.project_id=$PROJECT_ID + - --set + - common.cluster_name=${_GKE_CLUSTER} + - --set + - common.compute_zone=${_GKE_COMPUTE_ZONE} + - --set + - common.cluster_namespace=${_NAMESPACE} - --set - django.image.repository=${_IMAGE_NAME} - --set - django.image.tag=$COMMIT_SHA - --set + - secret_manager.file_name=${_SETTINGS_NAME} + - --set + - django.env.django_settings_module=${_K8TS_DJANGO_SETTINGS_MODULE} + - --set + - django.env.postgres_host=${_K8TS_PG_HOST} + - --set + - django.env.postgres_port=${_K8TS_PG_PORT} + - --set - ingress.networking.domain=${_DOMAIN_NAME} - --set - ingress.networking.issuer.name=${_LETSENCRYPT_SERVER_TYPE} @@ -116,6 +130,8 @@ steps: - cloud_sql.env.cloudsql_connection_instance=${_CLOUDSQL_INSTANCE_CONNECTION_NAME} - --set - django.configmap.config_name=${_CONFIGMAP_FILE} + - --set + - common.service_account_key=${_IAM_SERVICE_ACCOUNT_KEY} - . # Update essential Variables and Deploy to cluster @@ -127,17 +143,34 @@ steps: args: - upgrade - --install - - ${_APP_NAME}-${_DEPLOYMENT_TYPE} + - --debug + - --atomic + - --create-namespace - --namespace=${_NAMESPACE} + - ${_APP_NAME}-${_DEPLOYMENT_TYPE} - --values - values.yaml - --set - - namespace=${_NAMESPACE} + - common.project_id=$PROJECT_ID + - --set + - common.cluster_name=${_GKE_CLUSTER} + - --set + - common.compute_zone=${_GKE_COMPUTE_ZONE} + - --set + - common.cluster_namespace=${_NAMESPACE} - --set - django.image.repository=${_IMAGE_NAME} - --set - django.image.tag=$COMMIT_SHA - --set + - secret_manager.file_name=${_SETTINGS_NAME} + - --set + - django.env.django_settings_module=${_K8TS_DJANGO_SETTINGS_MODULE} + - --set + - django.env.postgres_host=${_K8TS_PG_HOST} + - --set + - django.env.postgres_port=${_K8TS_PG_PORT} + - --set - ingress.networking.domain=${_DOMAIN_NAME} - --set - ingress.networking.issuer.name=${_LETSENCRYPT_SERVER_TYPE} @@ -153,6 +186,8 @@ steps: - cloud_sql.env.cloudsql_connection_instance=${_CLOUDSQL_INSTANCE_CONNECTION_NAME} - --set - django.configmap.config_name=${_CONFIGMAP_FILE} + - --set + - common.service_account_key=${_IAM_SERVICE_ACCOUNT_KEY} - . images: diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..7818fc1 --- /dev/null +++ b/deploy/README.md @@ -0,0 +1 @@ +### Introduction diff --git a/deploy/ReadMe.md b/deploy/ReadMe.md deleted file mode 100644 index e69de29..0000000 diff --git a/deploy/templates/01_common/01_service_account.yaml b/deploy/templates/01_common/01_service_account.yaml new file mode 100644 index 0000000..8bd3cb6 --- /dev/null +++ b/deploy/templates/01_common/01_service_account.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.common.service_account_name }} + namespace: {{ .Values.common.cluster_namespace }} +type: Opaque +data: + # base64 -w 0 /path/to/sa_key.json + service_account.json: {{ .Values.common.service_account_key }} diff --git a/deploy/templates/pg-bouncer/dbuser_configmap.yml b/deploy/templates/02_pg_bouncer/01_dbuser_configmap.yml similarity index 84% rename from deploy/templates/pg-bouncer/dbuser_configmap.yml rename to deploy/templates/02_pg_bouncer/01_dbuser_configmap.yml index ffa2141..11f23a2 100644 --- a/deploy/templates/pg-bouncer/dbuser_configmap.yml +++ b/deploy/templates/02_pg_bouncer/01_dbuser_configmap.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ .Values.pg_bouncer.app_name }}-user-config + namespace: {{ .Values.common.cluster_namespace }} data: # echo -n '"user" "pa$$worLd"' | base64 userlist.txt: | diff --git a/deploy/templates/pg-bouncer/db_configmap.yml b/deploy/templates/02_pg_bouncer/02_db_configmap.yml similarity index 88% rename from deploy/templates/pg-bouncer/db_configmap.yml rename to deploy/templates/02_pg_bouncer/02_db_configmap.yml index 18ebc82..a1f53fc 100644 --- a/deploy/templates/pg-bouncer/db_configmap.yml +++ b/deploy/templates/02_pg_bouncer/02_db_configmap.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ .Values.pg_bouncer.app_name }}-db-config + namespace: {{ .Values.common.cluster_namespace }} data: POSTGRESQL_DB: {{ .Values.pg_bouncer.env.db_name }} POSTGRESQL_USERNAME: {{ .Values.pg_bouncer.env.db_user }} diff --git a/deploy/templates/pg-bouncer/pgb_configmap.yml b/deploy/templates/02_pg_bouncer/03_pgb_configmap.yml similarity index 92% rename from deploy/templates/pg-bouncer/pgb_configmap.yml rename to deploy/templates/02_pg_bouncer/03_pgb_configmap.yml index d6b5da9..87f1266 100644 --- a/deploy/templates/pg-bouncer/pgb_configmap.yml +++ b/deploy/templates/02_pg_bouncer/03_pgb_configmap.yml @@ -2,6 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: {{ .Values.pg_bouncer.app_name }}-pgb-config + namespace: {{ .Values.common.cluster_namespace }} data: pgbouncer.ini: | [databases] diff --git a/deploy/templates/pg-bouncer/deployment.yaml b/deploy/templates/02_pg_bouncer/04_deployment.yaml similarity index 84% rename from deploy/templates/pg-bouncer/deployment.yaml rename to deploy/templates/02_pg_bouncer/04_deployment.yaml index d5a3c0c..4d29ce2 100644 --- a/deploy/templates/pg-bouncer/deployment.yaml +++ b/deploy/templates/02_pg_bouncer/04_deployment.yaml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Values.pg_bouncer.app_name }} - namespace: {{ .Values.namespace }} + namespace: {{ .Values.common.cluster_namespace }} spec: replicas: {{ .Values.pg_bouncer.replica_count }} selector: @@ -34,12 +34,12 @@ spec: - "--structured-logs" - "--port=5432" - "{{ .Values.cloud_sql.env.cloudsql_connection_instance }}" - - "--credentials-file=/secrets/service_account_secrets/service_account.json" + - "--credentials-file=/secrets/{{ .Values.common.service_account_name }}/service_account.json" securityContext: runAsNonRoot: true volumeMounts: - name: sa-secret-vol - mountPath: /secrets/service_account_secrets + mountPath: "/secrets/{{ .Values.common.service_account_name }}" readOnly: true volumes: - name: user-config @@ -52,4 +52,4 @@ spec: - name: sa-secret-vol secret: - secretName: {{ .Values.namespace }}-sa-secrets + secretName: {{ .Values.common.service_account_name }} diff --git a/deploy/templates/pg-bouncer/service.yaml b/deploy/templates/02_pg_bouncer/05_service.yaml similarity index 90% rename from deploy/templates/pg-bouncer/service.yaml rename to deploy/templates/02_pg_bouncer/05_service.yaml index 9aae673..7009a55 100644 --- a/deploy/templates/pg-bouncer/service.yaml +++ b/deploy/templates/02_pg_bouncer/05_service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: name: {{ .Values.pg_bouncer.app_name }}-service - namespace: {{ .Values.namespace }} + namespace: {{ .Values.common.cluster_namespace }} annotations: cloud.google.com/load-balancer-type: "Internal" labels: diff --git a/deploy/templates/03_django/01_confimap_job.yml b/deploy/templates/03_django/01_confimap_job.yml new file mode 100644 index 0000000..4719ac3 --- /dev/null +++ b/deploy/templates/03_django/01_confimap_job.yml @@ -0,0 +1,104 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: configmap-creator + namespace: {{ .Values.common.cluster_namespace }} +spec: + template: + metadata: + name: configmap-creator + spec: + restartPolicy: OnFailure + containers: + - name: configmap-creator + image: gcr.io/google.com/cloudsdktool/cloud-sdk:459.0.0 + env: + - name: PROJECT_ID + value: {{ .Values.common.project_id }} + - name: CLUSTER_NAME + value: {{ .Values.common.cluster_name }} + - name: COMPUTE_ZONE + value: {{ .Values.common.compute_zone }} + - name: K8TS_DJANGO_SETTINGS_MODULE + value: {{ .Values.django.env.django_settings_module }} + - name: K8TS_POSTGRES_HOST + value: {{ .Values.django.env.postgres_host }} + - name: K8TS_POSTGRES_PORT + value: {{ .Values.django.env.postgres_port | quote }} + # Avoid issues with passwords with special characters + - name: K8TS_POSTGRES_PASSWORD + value: {{ .Values.pg_bouncer.env.db_password }} + - name: SECRET_MANAGER_FILE_NAME + value: {{ .Values.secret_manager.file_name }} + - name: CONFIGMAP_NAME + value: {{ .Values.django.configmap.config_name }} + - name: SERVICE_ACCOUNT_NAME + value: {{ .Values.common.service_account_name }} + command: ["/bin/sh", "-c"] + args: + - | + set -e + # Step 1: Authenticate with Google Cloud using the provided service account key + gcloud auth activate-service-account --key-file=/secrets/${SERVICE_ACCOUNT_NAME}/service_account.json + + # Step 2: Get the credentials for the GKE cluster and set up kubectl configuration. + gcloud container clusters get-credentials ${CLUSTER_NAME} --zone=${COMPUTE_ZONE} --project=$PROJECT_ID + + # Step 3: Fetch the latest version of the specified secret from Secret Manager + gcloud secrets versions access latest --secret=${SECRET_MANAGER_FILE_NAME} > /secrets/test_settings.txt + ENV_VARS="/secrets/test_settings.txt" + . "$ENV_VARS" + MY_CONTEXT=$(kubectl config get-contexts) + CONFIG_VIEW=$(kubectl config view) + echo "MY_CONTEXT: $MY_CONTEXT" + echo "CONFIG_VIEW: $CONFIG_VIEW" + echo "Override some variables that was used to create containers at cloudbuild" + kubectl create configmap $CONFIGMAP_NAME \ + --from-literal=PORT="8080" \ + --from-literal=CONN_MAX_AGE="$CONN_MAX_AGE" \ + --from-literal=COMPRESS_ENABLED="$COMPRESS_ENABLED" \ + --from-literal=DJANGO_ACCOUNT_ALLOW_REGISTRATION="$DJANGO_ACCOUNT_ALLOW_REGISTRATION" \ + --from-literal=DJANGO_ADMIN_URL="$DJANGO_ADMIN_URL" \ + --from-literal=DJANGO_ALLOWED_HOSTS="$DJANGO_ALLOWED_HOSTS" \ + --from-literal=DJANGO_DEBUG="$DJANGO_DEBUG" \ + --from-literal=DJANGO_DEFAULT_FROM_EMAIL="$DJANGO_DEFAULT_FROM_EMAIL" \ + --from-literal=DJANGO_EMAIL_SUBJECT_PREFIX="$DJANGO_EMAIL_SUBJECT_PREFIX" \ + --from-literal=DJANGO_GCP_STORAGE_BUCKET_NAME="$DJANGO_GCP_STORAGE_BUCKET_NAME" \ + --from-literal=DJANGO_READ_DOT_ENV_FILE="$DJANGO_READ_DOT_ENV_FILE" \ + --from-literal=DJANGO_SECRET_KEY="$DJANGO_SECRET_KEY" \ + --from-literal=DJANGO_SECURE_BROWSER_XSS_FILTER="$DJANGO_SECURE_BROWSER_XSS_FILTER" \ + --from-literal=DJANGO_SECURE_CONTENT_TYPE_NOSNIFF="$DJANGO_SECURE_CONTENT_TYPE_NOSNIFF" \ + --from-literal=DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS="$DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS" \ + --from-literal=DJANGO_SECURE_FRAME_DENY="$DJANGO_SECURE_FRAME_DENY" \ + --from-literal=DJANGO_SECURE_SSL_REDIRECT="$DJANGO_SECURE_SSL_REDIRECT" \ + --from-literal=DJANGO_SERVER_EMAIL="$DJANGO_SERVER_EMAIL" \ + --from-literal=DJANGO_SESSION_COOKIE_HTTPONLY="$DJANGO_SESSION_COOKIE_HTTPONLY" \ + --from-literal=DJANGO_SESSION_COOKIE_SECURE="$DJANGO_SESSION_COOKIE_SECURE" \ + --from-literal=DJANGO_SETTINGS_MODULE=${K8TS_DJANGO_SETTINGS_MODULE} \ + --from-literal=GOOGLE_ANALYTICS_ID="$GOOGLE_ANALYTICS_ID" \ + --from-literal=GOOGLE_APPLICATION_CREDENTIALS_KEY="$GOOGLE_APPLICATION_CREDENTIALS_KEY" \ + --from-literal=GOOGLE_CLOUD_PROJECT="$GOOGLE_CLOUD_PROJECT" \ + --from-literal=INSTANCE_CONNECTION_NAME="$INSTANCE_CONNECTION_NAME" \ + --from-literal=MAILGUN_DOMAIN="$MAILGUN_DOMAIN" \ + --from-literal=MAILGUN_API_URL="$MAILGUN_API_URL" \ + --from-literal=MAILGUN_API_KEY="$MAILGUN_API_KEY" \ + --from-literal=POSTGRES_DB="$POSTGRES_DB" \ + --from-literal=POSTGRES_HOST="${K8TS_POSTGRES_HOST}" \ + --from-literal=POSTGRES_PORT="${K8TS_POSTGRES_PORT}" \ + --from-literal=POSTGRES_PASSWORD="${K8TS_POSTGRES_PASSWORD}" \ + --from-literal=POSTGRES_USER="$POSTGRES_USER" \ + --from-literal=PUB_SUB_TOPIC="$PUB_SUB_TOPIC" \ + --from-literal=SENTRY_DSN="$SENTRY_DSN" \ + --from-literal=SENTRY_ENVIRONMENT="$SENTRY_ENVIRONMENT" \ + --from-literal=USE_DOCKER="$USE_DOCKER" \ + --from-literal=WEB_CONCURRENCY="$WEB_CONCURRENCY" \ + --from-literal=WHITELISTED_DOMAINS="$WHITELISTED_DOMAINS" + + volumeMounts: + - name: service-account-vol + mountPath: "/secrets/{{ .Values.common.service_account_name }}" + readOnly: true + volumes: + - name: service-account-vol + secret: + secretName: {{ .Values.common.service_account_name }} diff --git a/deploy/templates/django/deployment.yaml b/deploy/templates/03_django/02_deployment.yml similarity index 88% rename from deploy/templates/django/deployment.yaml rename to deploy/templates/03_django/02_deployment.yml index a3102ec..566ed6f 100644 --- a/deploy/templates/django/deployment.yaml +++ b/deploy/templates/03_django/02_deployment.yml @@ -2,7 +2,7 @@ apiVersion: apps/v1 kind: Deployment metadata: name: {{ .Values.django.app_name }} - namespace: {{ .Values.namespace }} + namespace: {{ .Values.common.cluster_namespace }} labels: app: {{ .Values.django.app_name }} spec: @@ -28,7 +28,7 @@ spec: name: {{ .Values.django.configmap.config_name }} volumeMounts: - name: env-var-vol - mountPath: /secrets/environment_variables + mountPath: "/secrets/{{ .Values.django.configmap.config_name }}" readOnly: true volumes: diff --git a/deploy/templates/django/service.yaml b/deploy/templates/03_django/03_service.yaml similarity index 88% rename from deploy/templates/django/service.yaml rename to deploy/templates/03_django/03_service.yaml index f894eb7..f94cd54 100644 --- a/deploy/templates/django/service.yaml +++ b/deploy/templates/03_django/03_service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: name: {{ .Values.django.app_name }}-service - namespace: {{ .Values.namespace }} + namespace: {{ .Values.common.cluster_namespace }} labels: app: {{ .Values.django.app_name }} spec: diff --git a/deploy/templates/ingress/ingress.yaml b/deploy/templates/04_ingress/01_ingress.yaml similarity index 94% rename from deploy/templates/ingress/ingress.yaml rename to deploy/templates/04_ingress/01_ingress.yaml index 0d401f8..e634ffa 100644 --- a/deploy/templates/ingress/ingress.yaml +++ b/deploy/templates/04_ingress/01_ingress.yaml @@ -2,7 +2,7 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ .Values.ingress.app_name }} - namespace: {{ .Values.namespace }} + namespace: {{ .Values.common.cluster_namespace }} annotations: cert-manager.io/issuer: {{ .Values.ingress.networking.issuer.name }} konghq.com/protocols: "http,https" diff --git a/deploy/templates/ingress/cert_issuer.yaml b/deploy/templates/04_ingress/02_cert_issuer.yaml similarity index 91% rename from deploy/templates/ingress/cert_issuer.yaml rename to deploy/templates/04_ingress/02_cert_issuer.yaml index 11b4f41..9566b5c 100644 --- a/deploy/templates/ingress/cert_issuer.yaml +++ b/deploy/templates/04_ingress/02_cert_issuer.yaml @@ -2,7 +2,7 @@ apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: {{ .Values.ingress.networking.issuer.name }} - namespace: {{ .Values.namespace }} + namespace: {{ .Values.common.cluster_namespace }} spec: acme: server: {{ .Values.ingress.networking.issuer.acme.server }} diff --git a/deploy/values.yaml b/deploy/values.yaml index 5e66c1f..179df06 100644 --- a/deploy/values.yaml +++ b/deploy/values.yaml @@ -1,4 +1,10 @@ -namespace: cluster_namespace +common: + project_id: "project-id" + cluster_name: "cluster-name" + compute_zone: "compute-zone" + cluster_namespace: "work-namespace" + service_account_key: "base64_encoded_sa_key" + service_account_name: "iam-service-account-key" django: app_name: django @@ -15,6 +21,10 @@ django: config_name: "config_name" secrets: secrets_name: "secrets_name" + env: + django_settings_module: django_settings_module + postgres_host: postgres_host + postgres_port: postgres_port cloud_sql: app_name: cloudsql-proxy @@ -41,6 +51,9 @@ pg_bouncer: db_user: "database_user" db_password: "database_password" +secret_manager: + file_name: secret_manager_file_name + ingress: app_name: ingress networking: