Skip to content
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 }}
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 }}
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
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