https://github.com/bzon/ecr-k8s-secret-creator
A Kubernetes client that creates a Secret for docker clients authenticating to ECR.
https://github.com/bzon/ecr-k8s-secret-creator
aws-ecr docker ecr go golang kubernetes weave-flux
Last synced: 3 months ago
JSON representation
A Kubernetes client that creates a Secret for docker clients authenticating to ECR.
- Host: GitHub
- URL: https://github.com/bzon/ecr-k8s-secret-creator
- Owner: bzon
- License: mit
- Created: 2018-08-30T13:09:39.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2022-08-22T22:21:08.000Z (about 3 years ago)
- Last Synced: 2025-06-09T02:40:54.156Z (4 months ago)
- Topics: aws-ecr, docker, ecr, go, golang, kubernetes, weave-flux
- Language: Go
- Homepage:
- Size: 72.3 KB
- Stars: 42
- Watchers: 4
- Forks: 15
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://goreportcard.com/report/github.com/bzon/ecr-k8s-secret-creator)
[](https://codecov.io/gh/bzon/ecr-k8s-secret-creator)
[](https://travis-ci.org/bzon/ecr-k8s-secret-creator)# NO MAINTENANCE NOTICE
I don't maintain this repository anymore. Feel free to fork if needed.
# ECR K8S Secret Creator
This application creates a docker config.json (as a Kubernetes secret) that can authenticate docker clients to Amazon ECR. It is using the [ECR GetAuthorizationToken API](https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_GetAuthorizationToken.html) to fetch the token from an Amazon Region.
A docker config.json file looks like this, which may be found in `$HOME/.docker/config.json` after using `docker login`.
```json
{
"auths": {
"https://${AWS_PROFILE}.dkr.ecr.us-east-1.amazonaws.com": {
"auth": "....."
}
}
}
```This application is like a running cron job that does `aws ecr get-login`, creates a docker config.json file, then create Kubernetes secret out of it.
**WARNING!!** If you need to run this in production environments, please build your own Docker image by following the [How To Build this Project](#how-to-build-this-project) step.
## How does it work?
* Deploy this application as a Pod in the namespace to create the Secret.
* This Pod authenticates to AWS to get a new ECR docker login token according to the `-region` flag.
* It then creates a config.json according to the values retrieved from AWS.
```go
# config.json template
const cfgTemplate = `{
"auths": {
"{{ .registry }}": {
"auth": "{{ .token }}"
}
}
}`
```* It then creates or updates the Secret according to the `-secretName` flag in the current namespace.
```yaml
apiVersion: v1
type: Secret
metadata:
name: xxxx # -secretName
namespace: xxxx # current pod namespace
data:
config.json: xxxxx # base64 encoded
```* You can specify secret type by using `-secretType` flag. This can be useful, when running kubernetes nodes outside of AWS, as in this scenario kubelet does not have pull access to ECR. Specifying `-secretType=kubernetes.io/dockerconfigjson` will automate creation of a secret, that can be used in manifests requiring `imagePullSecrets`
```yaml
apiVersion: v1
data:
.dockerconfigjson: xxxxx
kind: Secret
type: kubernetes.io/dockerconfigjson
metadata:
name: xxxx
namespace: xxxx
```* It repeats the process according to the specified `-interval` flag. Refreshing the config.json file content in the Secret over the time specified.
* You can now use this kubernetes secret and __mount__ it to any pod that has a docker client that authenticates to ECR.
## Why did I create this?
We are using [Weave Flux](https://github.com/weaveworks/flux) to operate our __GitOps__ deployment process. The Weave Flux operator currently does not support authentication to ECR ([issue #539](https://github.com/weaveworks/flux/issues/539)). As a workaround, we can use the `--docker-config` flag and mount a custom `config.json` in the flux Pod ([issue #1065](https://github.com/weaveworks/flux/pull/1065)).
The problem is ECR token expires every 12 hours, and we need to find a way to ensure that the config.json authentication token is rotated in an automated and secure way.
## How to use with Weave Flux Pod?
Complete the [Deployment Guide](#deployment), noting the secret name and then follow [Flux Guide](https://github.com/bzon/ecr-k8s-secret-creator/blob/master/FLUX_GUIDE.md).
## How to Deploy
* [IAM Role Requirement](#iam-role-requirement)
* [Deployment](#deployment)
* [Check the ECR Secret Creator Pod's logs](#check-the-ecr-secret-creator-pods-logs)
* [Check the Created Secret](#check-the-created-secret)
* [How to Build this Project](#how-to-build-this-project)### IAM Role Requirement
If you are __NOT__ using [kube2iam](https://github.com/jtblin/kube2iam), skip to the [Deployment Step](#deployment) and ensure that your Pod's EC2 instance can authenticate to your AWS Account via AWS API Keys, or AWS EC2 IAM Role.
__Create IAM Policy__
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
}
]
}
``````bash
aws iam create-policy --policy-name ${GET_ECR_AUTH_IAM_POLICY} --policy-document file://iam-policy.json --description "A policy that can get ECR authorization token"
```__Create IAM Role__
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${AWS_PROFILE}:role/${IAM_K8S_NODE_ROLE}"
},
"Action": "sts:AssumeRole"
}
]
}
``````bash
aws iam create-role --role-name ${GET_ECR_AUTH_IAM_ROLE} \
--assume-role-policy-document file://ec2-iam-trust.json
```__Attach the IAM Policy__
```bash
aws iam attach-role-policy --role-name ${GET_ECR_AUTH_IAM_ROLE} \
--policy-arn arn:aws:iam::${AWS_PROFILE}:policy/${GET_ECR_AUTH_IAM_POLICY}
```### Deployment
Create the following RBAC and deploy resources yaml files and run `kubectl apply -f`.
```yaml
---
kind: ServiceAccount
apiVersion: v1
metadata:
name: ecr-k8s-secret-creator
namespace: ${SECRET_NAMESPACE}
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ecr-k8s-secret-creator
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ecr-k8s-secret-creator
roleRef:
kind: ClusterRole
name: ecr-k8s-secret-creator
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: ecr-k8s-secret-creator
namespace: ${SECRET_NAMESPACE}
``````yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ecr-k8s-secret-creator
namespace: ${SECRET_NAMESPACE}
spec:
replicas: 1
selector:
matchLabels:
app: ecr-k8s-secret-creator
template:
metadata:
labels:
app: ecr-k8s-secret-creator
# if using kube2iam
# annotations:
# iam.amazonaws.com/role: arn:aws:iam::${AWS_PROFILE}:role/${GET_ECR_AUTH_IAM_ROLE}
spec:
serviceAccount: ecr-k8s-secret-creator
containers:
- image: bzon/ecr-k8s-secret-creator:latest
name: ecr-k8s-secret-creator
args:
- "-secretName=ecr-docker-secret"
- "-region=us-east-1"
# the default profile is the AWS account where the kubernetes cluster is running
# - "-profile=${AWS_ACCOUNT_ID}"
# the default interval for fetching new ecr token is 200 seconds
# - "-interval=300"
resources:
requests:
cpu: 5m
memory: 16Mi
limits:
cpu: 20m
memory: 32Mi
```### Check the ECR Secret Creator Pod's logs
```json
{"level":"info","msg":"appVersion: 0.1.0","time":"2018-09-29T16:48:17Z"}
{"level":"info","msg":"Flags: region=us-east-1, interval=1200, profile=, secretName=ecr-docker-secret","time":"2018-09-29T16:48:17Z"}
{"level":"info","msg":"creating kubernetes secret","time":"2018-09-29T16:48:19Z"}
{"level":"info","msg":"updated kubernetes secret: ecr-docker-secret","time":"2018-09-29T16:48:19Z"}
```### Check the Created Secret
```bash
kubectl get secrets ecr-docker-secret -n ${SECRET_NAMESPACE} -o json | jq '.data["config.json"]' | tr -d '"' | base64 --decode{
"auths": {
"https://${AWS_PROFILE}.dkr.ecr.us-east-1.amazonaws.com": {
"auth": "....."
}
}
}
```## How to Build this Project
* Install [Go](https://golang.github.io/dep/docs/installation.html)
* Download the project `go get github.com/bzon/ecr-k8s-secret-creator`
* Go to `$GOPATH/github.com/bzon/ecr-k8s-secret-creator`
* Change the docker repository in the `Makefile` to your own docker repository
* Run `make docker-build`
* Run `make push`