Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added helm chart for updating AWS ECR secrets in Kubernetes #228

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions charts/renew-ecr-k8s-creds/Chart.yaml
Original file line number Diff line number Diff line change
@@ -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

47 changes: 47 additions & 0 deletions charts/renew-ecr-k8s-creds/README.md
Original file line number Diff line number Diff line change
@@ -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
```
24 changes: 24 additions & 0 deletions charts/renew-ecr-k8s-creds/templates/job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: renew-ecr-k8s-creds
namespace: {{ .Values.kubernetes.namespace }}
vishu247 marked this conversation as resolved.
Show resolved Hide resolved
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
9 changes: 9 additions & 0 deletions charts/renew-ecr-k8s-creds/templates/role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: {{ .Values.kubernetes.namespace }}
vishu247 marked this conversation as resolved.
Show resolved Hide resolved
name: renew-ecr-k8s-creds-role
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "create", "patch"]
13 changes: 13 additions & 0 deletions charts/renew-ecr-k8s-creds/templates/rolebinding.yaml
Original file line number Diff line number Diff line change
@@ -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
56 changes: 56 additions & 0 deletions charts/renew-ecr-k8s-creds/templates/script-configmap.yaml
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions charts/renew-ecr-k8s-creds/templates/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
vishu247 marked this conversation as resolved.
Show resolved Hide resolved
kind: ServiceAccount
metadata:
name: {{ .Values.serviceAccount.name }}
namespace: {{ .Values.kubernetes.namespace }}

26 changes: 26 additions & 0 deletions charts/renew-ecr-k8s-creds/values.yaml
Original file line number Diff line number Diff line change
@@ -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
Loading