Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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

45 changes: 45 additions & 0 deletions charts/renew-ecr-k8s-creds/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 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:
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:
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: {{ .Release.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
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: {{ .Release.Namespace }}
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: {{ .Release.Namespace }}
subjects:
- kind: ServiceAccount
name: {{ .Values.serviceAccount.name }}
namespace: {{ .Release.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: {{ .Release.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="{{ .Release.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="{{ .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="{{ .Release.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
kind: ServiceAccount
metadata:
name: {{ .Values.serviceAccount.name }}
namespace: {{ .Release.Namespace }}

24 changes: 24 additions & 0 deletions charts/renew-ecr-k8s-creds/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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:
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:
name: "renew-ecr-k8s-creds-sa" # Name of the ServiceAccount to create or use