From 2c6b58e54a1d137d26145b7406539fed67263fd0 Mon Sep 17 00:00:00 2001 From: vishugoyal Date: Mon, 24 Jun 2024 19:37:06 +0530 Subject: [PATCH 1/8] Helm chart for updating AWS ECR secrets in Kubernetes --- charts/renew-ecr-k8s-creds/Chart.yaml | 5 ++ charts/renew-ecr-k8s-creds/README.md | 47 ++++++++++++++++ charts/renew-ecr-k8s-creds/templates/job.yaml | 24 ++++++++ .../renew-ecr-k8s-creds/templates/role.yaml | 9 +++ .../templates/rolebinding.yaml | 13 +++++ .../templates/script-configmap.yaml | 56 +++++++++++++++++++ .../templates/serviceaccount.yaml | 6 ++ charts/renew-ecr-k8s-creds/values.yaml | 26 +++++++++ 8 files changed, 186 insertions(+) create mode 100644 charts/renew-ecr-k8s-creds/Chart.yaml create mode 100644 charts/renew-ecr-k8s-creds/README.md create mode 100644 charts/renew-ecr-k8s-creds/templates/job.yaml create mode 100644 charts/renew-ecr-k8s-creds/templates/role.yaml create mode 100644 charts/renew-ecr-k8s-creds/templates/rolebinding.yaml create mode 100644 charts/renew-ecr-k8s-creds/templates/script-configmap.yaml create mode 100644 charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml create mode 100644 charts/renew-ecr-k8s-creds/values.yaml diff --git a/charts/renew-ecr-k8s-creds/Chart.yaml b/charts/renew-ecr-k8s-creds/Chart.yaml new file mode 100644 index 00000000..52080155 --- /dev/null +++ b/charts/renew-ecr-k8s-creds/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: renew-ecr-k8s-creds +description: A Helm chart for updating AWS ECR secrets in Kubernetes +version: 0.1.0 + diff --git a/charts/renew-ecr-k8s-creds/README.md b/charts/renew-ecr-k8s-creds/README.md new file mode 100644 index 00000000..f1aa1a33 --- /dev/null +++ b/charts/renew-ecr-k8s-creds/README.md @@ -0,0 +1,47 @@ +# renew-ecr-k8s-cred + +A Helm chart for renewing AWS ECR credentials and updating them in a Kubernetes secret. + +## Introduction + +This Helm chart creates a CronJob in Kubernetes to periodically renew AWS Elastic Container Registry (ECR) credentials and update them in a Kubernetes secret. This is useful for ensuring that your ECR credentials are always up to date, especially in environments where long-running workloads need continuous access to private ECR repositories. + +## Prerequisites + +- Kubernetes 1.16+ +- Helm 3.0+ +- An AWS account with permissions to assume the specified role and access ECR +- The AWS CLI installed in the container image + +## Installation + +### Add the Helm Repository + +```sh +# AWS credentials configuration +aws: + accessKey: "your-aws-access-key" # AWS Access Key ID of IAM role for authentication + secretKey: "your-aws-secret-key" # AWS Secret Access Key of IAM role for authentication + region: "your-aws-region" # AWS region where your resources are located + roleArn: "your-aws-role-arn" # ARN of the AWS role to assume for getting temporary credentials + sessionName: "your-session-name" # Session name for the assumed role + +# Kubernetes configuration +kubernetes: + namespace: "your-namespace" # Namespace in which to create or update the Kubernetes secret + secretName: "your-secret-name" # Name of the Kubernetes secret to create or update with ECR credentials + +# ECR (Elastic Container Registry) configuration +ecr: + account: "your-aws-account" # AWS account ID where your ECR is located + region: "your-ecr-region" # AWS region of your ECR + +# CronJob configuration +cronjob: + schedule: "0 */12 * * *" # Cron schedule for the job to run (every 12 hours) + +# ServiceAccount configuration +serviceAccount: + create: true # Set to true to create a new ServiceAccount, false to use an existing one + name: "renew-ecr-k8s-creds-sa" # Name of the ServiceAccount to create or use +``` diff --git a/charts/renew-ecr-k8s-creds/templates/job.yaml b/charts/renew-ecr-k8s-creds/templates/job.yaml new file mode 100644 index 00000000..be0c411b --- /dev/null +++ b/charts/renew-ecr-k8s-creds/templates/job.yaml @@ -0,0 +1,24 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: renew-ecr-k8s-creds + namespace: {{ .Values.kubernetes.namespace }} +spec: + schedule: "{{ .Values.cronjob.schedule }}" + jobTemplate: + spec: + template: + spec: + serviceAccountName: {{ .Values.serviceAccount.name }} + containers: + - name: renew-ecr-k8s-creds + image: amazon/aws-cli:2.13.15 + command: ["/bin/bash", "/scripts/update-secret.sh"] + volumeMounts: + - name: script + mountPath: /scripts + restartPolicy: Never + volumes: + - name: script + configMap: + name: renew-ecr-k8s-creds-script diff --git a/charts/renew-ecr-k8s-creds/templates/role.yaml b/charts/renew-ecr-k8s-creds/templates/role.yaml new file mode 100644 index 00000000..0a68e256 --- /dev/null +++ b/charts/renew-ecr-k8s-creds/templates/role.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: {{ .Values.kubernetes.namespace }} + name: renew-ecr-k8s-creds-role +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create", "patch"] diff --git a/charts/renew-ecr-k8s-creds/templates/rolebinding.yaml b/charts/renew-ecr-k8s-creds/templates/rolebinding.yaml new file mode 100644 index 00000000..5284062b --- /dev/null +++ b/charts/renew-ecr-k8s-creds/templates/rolebinding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: renew-ecr-k8s-creds-rolebinding + namespace: {{ .Values.kubernetes.namespace }} +subjects: +- kind: ServiceAccount + name: {{ .Values.serviceAccount.name }} + namespace: {{ .Values.kubernetes.namespace }} +roleRef: + kind: Role + name: renew-ecr-k8s-creds-role + apiGroup: rbac.authorization.k8s.io diff --git a/charts/renew-ecr-k8s-creds/templates/script-configmap.yaml b/charts/renew-ecr-k8s-creds/templates/script-configmap.yaml new file mode 100644 index 00000000..d160cc9d --- /dev/null +++ b/charts/renew-ecr-k8s-creds/templates/script-configmap.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: renew-ecr-k8s-creds-script + namespace: {{ .Values.kubernetes.namespace }} +data: + update-secret.sh: | + #!/bin/bash + + # Install kubectl + echo "Installing kubectl..." + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl + + # Install jq + echo "Installing jq..." + yum install -y jq + + secret_exists() { + kubectl get secret "{{ .Values.kubernetes.secretName }}" --namespace="{{ .Values.kubernetes.namespace }}" &> /dev/null + return $? + } + + echo "Aws Configure..." + aws configure set aws_access_key_id "{{ .Values.aws.accessKey }}" + aws configure set aws_secret_access_key "{{ .Values.aws.secretKey }}" + aws configure set region "{{ .Values.aws.region }}" + aws configure set output "json" + + echo "Assuming a Role..." + ROLE_OUTPUT=$(aws sts assume-role --role-arn "{{ .Values.aws.roleArn }}" --role-session-name "{{ .Values.aws.sessionName }}") + + echo "Now fetching the access_key, secret_key & session_token..." + AWS_ACCESS_KEY_ID=$(echo "$ROLE_OUTPUT" | jq -r '.Credentials.AccessKeyId') + AWS_SECRET_ACCESS_KEY=$(echo "$ROLE_OUTPUT" | jq -r '.Credentials.SecretAccessKey') + AWS_SESSION_TOKEN=$(echo "$ROLE_OUTPUT" | jq -r '.Credentials.SessionToken') + + export AWS_ACCESS_KEY_ID + export AWS_SECRET_ACCESS_KEY + export AWS_SESSION_TOKEN + + if secret_exists; then + echo "Secret already exists, patching the secret..." + kubectl patch secret "{{ .Values.kubernetes.secretName }}" --namespace="{{ .Values.kubernetes.namespace }}" --type='json' -p='[{"op": "replace", "path": "/data/.dockerconfigjson", "value":"'$(echo -n "{\"auths\":{\"{{ .Values.ecr.account }}.dkr.ecr.{{ .Values.ecr.region }}.amazonaws.com\":{\"username\":\"AWS\",\"password\":\"$(aws ecr get-login-password)\"}}}" | base64 | tr -d '\n')'"}]' + else + echo "Secret does not exist, creating the secret..." + kubectl create secret docker-registry "{{ .Values.kubernetes.secretName }}" \ + --docker-server="{{ .Values.ecr.account }}.dkr.ecr.{{ .Values.ecr.region }}.amazonaws.com" \ + --docker-username=AWS \ + --docker-password="$(aws ecr get-login-password)" \ + --namespace="{{ .Values.kubernetes.namespace }}" + fi + + unset AWS_ACCESS_KEY_ID + unset AWS_SECRET_ACCESS_KEY + unset AWS_SESSION_TOKEN diff --git a/charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml b/charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml new file mode 100644 index 00000000..74f2c2ee --- /dev/null +++ b/charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.name }} + namespace: {{ .Values.kubernetes.namespace }} + diff --git a/charts/renew-ecr-k8s-creds/values.yaml b/charts/renew-ecr-k8s-creds/values.yaml new file mode 100644 index 00000000..788bcc48 --- /dev/null +++ b/charts/renew-ecr-k8s-creds/values.yaml @@ -0,0 +1,26 @@ +# AWS credentials configuration +aws: + accessKey: "your-aws-access-key" # AWS Access Key ID of IAM role for authentication + secretKey: "your-aws-secret-key" # AWS Secret Access Key of IAM role for authentication + region: "your-aws-region" # AWS region where your resources are located + roleArn: "your-aws-role-arn" # ARN of the AWS role to assume for getting temporary credentials + sessionName: "your-session-name" # Session name for the assumed role + +# Kubernetes configuration +kubernetes: + namespace: "your-namespace" # Namespace in which to create or update the Kubernetes secret + secretName: "your-secret-name" # Name of the Kubernetes secret to create or update with ECR credentials + +# ECR (Elastic Container Registry) configuration +ecr: + account: "your-aws-account" # AWS account ID where your ECR is located + region: "your-ecr-region" # AWS region of your ECR + +# CronJob configuration +cronjob: + schedule: "0 */12 * * *" # Cron schedule for the job to run (every 12 hours) + +# ServiceAccount configuration +serviceAccount: + create: true # Set to true to create a new ServiceAccount, false to use an existing one + name: "renew-ecr-k8s-creds-sa" # Name of the ServiceAccount to create or use From 134009db468f06c56323ef3c72ecd8e84ba0000e Mon Sep 17 00:00:00 2001 From: vishu247 <156403229+vishu247@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:21:25 +0530 Subject: [PATCH 2/8] update the job.yaml --- charts/renew-ecr-k8s-creds/templates/job.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/renew-ecr-k8s-creds/templates/job.yaml b/charts/renew-ecr-k8s-creds/templates/job.yaml index be0c411b..e19aab3c 100644 --- a/charts/renew-ecr-k8s-creds/templates/job.yaml +++ b/charts/renew-ecr-k8s-creds/templates/job.yaml @@ -2,7 +2,7 @@ apiVersion: batch/v1 kind: CronJob metadata: name: renew-ecr-k8s-creds - namespace: {{ .Values.kubernetes.namespace }} + namespace: {{ .Release.Namespace }} spec: schedule: "{{ .Values.cronjob.schedule }}" jobTemplate: From 34d8a20224258c941264213e0f7fb4a2143ce179 Mon Sep 17 00:00:00 2001 From: vishu247 <156403229+vishu247@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:21:45 +0530 Subject: [PATCH 3/8] Update role.yaml --- charts/renew-ecr-k8s-creds/templates/role.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/renew-ecr-k8s-creds/templates/role.yaml b/charts/renew-ecr-k8s-creds/templates/role.yaml index 0a68e256..0391634c 100644 --- a/charts/renew-ecr-k8s-creds/templates/role.yaml +++ b/charts/renew-ecr-k8s-creds/templates/role.yaml @@ -1,7 +1,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - namespace: {{ .Values.kubernetes.namespace }} + namespace: {{ .Release.Namespace }} name: renew-ecr-k8s-creds-role rules: - apiGroups: [""] From 5288f844f64e97263e2ebb80147b4f5cb7d19dd4 Mon Sep 17 00:00:00 2001 From: vishu247 <156403229+vishu247@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:38:36 +0530 Subject: [PATCH 4/8] Update rolebinding.yaml --- charts/renew-ecr-k8s-creds/templates/rolebinding.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/renew-ecr-k8s-creds/templates/rolebinding.yaml b/charts/renew-ecr-k8s-creds/templates/rolebinding.yaml index 5284062b..71740f0a 100644 --- a/charts/renew-ecr-k8s-creds/templates/rolebinding.yaml +++ b/charts/renew-ecr-k8s-creds/templates/rolebinding.yaml @@ -2,11 +2,11 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: renew-ecr-k8s-creds-rolebinding - namespace: {{ .Values.kubernetes.namespace }} + namespace: {{ .Release.Namespace }} subjects: - kind: ServiceAccount name: {{ .Values.serviceAccount.name }} - namespace: {{ .Values.kubernetes.namespace }} + namespace: {{ .Release.Namespace }} roleRef: kind: Role name: renew-ecr-k8s-creds-role From f2196b6eeec0761454bff05c0e50c842b09a7cf7 Mon Sep 17 00:00:00 2001 From: vishu247 <156403229+vishu247@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:39:45 +0530 Subject: [PATCH 5/8] Update script-configmap.yaml --- .../renew-ecr-k8s-creds/templates/script-configmap.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/charts/renew-ecr-k8s-creds/templates/script-configmap.yaml b/charts/renew-ecr-k8s-creds/templates/script-configmap.yaml index d160cc9d..49aada5c 100644 --- a/charts/renew-ecr-k8s-creds/templates/script-configmap.yaml +++ b/charts/renew-ecr-k8s-creds/templates/script-configmap.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: ConfigMap metadata: name: renew-ecr-k8s-creds-script - namespace: {{ .Values.kubernetes.namespace }} + namespace: {{ .Release.Namespace }} data: update-secret.sh: | #!/bin/bash @@ -17,7 +17,7 @@ data: yum install -y jq secret_exists() { - kubectl get secret "{{ .Values.kubernetes.secretName }}" --namespace="{{ .Values.kubernetes.namespace }}" &> /dev/null + kubectl get secret "{{ .Values.kubernetes.secretName }}" --namespace="{{ .Release.Namespace }}" &> /dev/null return $? } @@ -41,14 +41,14 @@ data: if secret_exists; then echo "Secret already exists, patching the secret..." - kubectl patch secret "{{ .Values.kubernetes.secretName }}" --namespace="{{ .Values.kubernetes.namespace }}" --type='json' -p='[{"op": "replace", "path": "/data/.dockerconfigjson", "value":"'$(echo -n "{\"auths\":{\"{{ .Values.ecr.account }}.dkr.ecr.{{ .Values.ecr.region }}.amazonaws.com\":{\"username\":\"AWS\",\"password\":\"$(aws ecr get-login-password)\"}}}" | base64 | tr -d '\n')'"}]' + kubectl patch secret "{{ .Values.kubernetes.secretName }}" --namespace="{{ .Release.Namespace }}" --type='json' -p='[{"op": "replace", "path": "/data/.dockerconfigjson", "value":"'$(echo -n "{\"auths\":{\"{{ .Values.ecr.account }}.dkr.ecr.{{ .Values.ecr.region }}.amazonaws.com\":{\"username\":\"AWS\",\"password\":\"$(aws ecr get-login-password)\"}}}" | base64 | tr -d '\n')'"}]' else echo "Secret does not exist, creating the secret..." kubectl create secret docker-registry "{{ .Values.kubernetes.secretName }}" \ --docker-server="{{ .Values.ecr.account }}.dkr.ecr.{{ .Values.ecr.region }}.amazonaws.com" \ --docker-username=AWS \ --docker-password="$(aws ecr get-login-password)" \ - --namespace="{{ .Values.kubernetes.namespace }}" + --namespace="{{ .Release.Namespace }}" fi unset AWS_ACCESS_KEY_ID From 29c72c241b2e6f6f22939091d13bd7af18761aef Mon Sep 17 00:00:00 2001 From: vishu247 <156403229+vishu247@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:40:04 +0530 Subject: [PATCH 6/8] Update serviceaccount.yaml --- charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml b/charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml index 74f2c2ee..8645420c 100644 --- a/charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml +++ b/charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml @@ -2,5 +2,5 @@ apiVersion: v1 kind: ServiceAccount metadata: name: {{ .Values.serviceAccount.name }} - namespace: {{ .Values.kubernetes.namespace }} + namespace: {{ .Release.Namespace }} From b64872594c4ee5f3340ee88809dc4b04874ec6f9 Mon Sep 17 00:00:00 2001 From: vishu247 <156403229+vishu247@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:40:56 +0530 Subject: [PATCH 7/8] Update values.yaml --- charts/renew-ecr-k8s-creds/values.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/charts/renew-ecr-k8s-creds/values.yaml b/charts/renew-ecr-k8s-creds/values.yaml index 788bcc48..341c61f0 100644 --- a/charts/renew-ecr-k8s-creds/values.yaml +++ b/charts/renew-ecr-k8s-creds/values.yaml @@ -8,7 +8,6 @@ aws: # Kubernetes configuration kubernetes: - namespace: "your-namespace" # Namespace in which to create or update the Kubernetes secret secretName: "your-secret-name" # Name of the Kubernetes secret to create or update with ECR credentials # ECR (Elastic Container Registry) configuration @@ -22,5 +21,4 @@ cronjob: # ServiceAccount configuration serviceAccount: - create: true # Set to true to create a new ServiceAccount, false to use an existing one name: "renew-ecr-k8s-creds-sa" # Name of the ServiceAccount to create or use From 10adc7eab48e6473fcfe946152589e694f1129d2 Mon Sep 17 00:00:00 2001 From: vishu247 <156403229+vishu247@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:42:37 +0530 Subject: [PATCH 8/8] Update README.md --- charts/renew-ecr-k8s-creds/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/charts/renew-ecr-k8s-creds/README.md b/charts/renew-ecr-k8s-creds/README.md index f1aa1a33..6ee93055 100644 --- a/charts/renew-ecr-k8s-creds/README.md +++ b/charts/renew-ecr-k8s-creds/README.md @@ -28,7 +28,6 @@ aws: # Kubernetes configuration kubernetes: - namespace: "your-namespace" # Namespace in which to create or update the Kubernetes secret secretName: "your-secret-name" # Name of the Kubernetes secret to create or update with ECR credentials # ECR (Elastic Container Registry) configuration @@ -42,6 +41,5 @@ cronjob: # ServiceAccount configuration serviceAccount: - create: true # Set to true to create a new ServiceAccount, false to use an existing one name: "renew-ecr-k8s-creds-sa" # Name of the ServiceAccount to create or use ```