Skip to content

Commit

Permalink
Initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
micahhausler committed Jun 17, 2019
1 parent b7e0941 commit 0048675
Show file tree
Hide file tree
Showing 28 changed files with 2,271 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.swp
amazon-eks-pod-identity-webhook
deploy/mutatingwebhook-ca-bundle.yaml
deploy/deployment.yaml
build
13 changes: 13 additions & 0 deletions .wwhrd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# github.com/frapposelli/wwhrd
# wwhrd check
---
whitelist:
- Apache-2.0
- MIT
- ISC
- NewBSD
- FreeBSD

exceptions:
- github.com/opencontainers/go-digest/... # uses Apache-2.0
- github.com/hashicorp/golang-lru/... # Mozilla
34 changes: 34 additions & 0 deletions Config
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*-perl-*-

package.AWSEKSPodIdentityWebhook = {
interfaces = (1.0);

deploy = {
generic = true;
map = (default, "-gopath/src/**", "-gopath/pkg/**");
};

build-environment = {
chroot = basic;
network-access = blocked;
};

build-system = bgo-wrap-make;
build-tools = {
1.0 = {
BrazilMakeGo = 2.0;
GoLang = 1.0;
};
};

dependencies = {
1.0 = {
};
};

runtime-dependencies = {
1.0 = {
};
};

};
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM golang AS builder

WORKDIR $GOPATH/src/github.com/aws/amazon-eks-pod-identity-webhook
COPY . ./
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix nocgo -o /webhook .

FROM scratch
COPY --from=builder /webhook /webhook
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
EXPOSE 443
VOLUME /etc/webhook
ENTRYPOINT ["/webhook"]
CMD ["--logtostderr"]
61 changes: 61 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# AWS-specific make args
-include build/private/bgo_exports.makefile
include ${BGO_MAKEFILE}

GO_INSTALL_FLAGS=-ldflags="-s -w"

# Generic make
REGISTRY_ID?=602401143452
IMAGE_NAME?=eks/iam-for-pods
REGION?=us-west-2
IMAGE?=$(REGISTRY_ID).dkr.ecr.$(REGION).amazonaws.com/$(IMAGE_NAME)

docker:
@echo 'Building image $(IMAGE)...'
docker build --no-cache -t $(IMAGE) .

push: docker
eval $$(aws ecr get-login --registry-ids $(REGISTRY_ID) --no-include-email)
docker push $(IMAGE)

amazon-eks-pod-identity-webhook:
go build

serve-local: amazon-eks-pod-identity-webhook
./amazon-eks-pod-identity-webhook \
--port 8443 \
--in-cluster=false

local-request:
curl \
-k \
-H "Content-Type: application/json" \
-X POST \
-d @hack/request.json \
https://localhost:8443/mutate | jq

# cluster commands
cluster-up: deploy-config

cluster-down: delete-config

prep-config:
@echo 'Generating certs and deploying into active cluster...'
cat deploy/deployment-base.yaml | sed -e "s|IMAGE|${IMAGE}|g" | tee deploy/deployment.yaml
cat deploy/mutatingwebhook.yaml | hack/webhook-patch-ca-bundle.sh > deploy/mutatingwebhook-ca-bundle.yaml

deploy-config: prep-config
@echo 'Applying configuration to active cluster...'
kubectl apply -f deploy/auth.yaml
kubectl apply -f deploy/deployment.yaml
kubectl apply -f deploy/service.yaml
kubectl apply -f deploy/mutatingwebhook-ca-bundle.yaml
sleep 1
kubectl certificate approve $$(kubectl get csr -o jsonpath='{.items[?(@.spec.username=="system:serviceaccount:eks:iam-for-pods")].metadata.name}') \

delete-config:
@echo 'Tearing down mutating controller and associated resources...'
kubectl delete -f deploy/mutatingwebhook-ca-bundle.yaml
kubectl delete -f deploy/service.yaml
kubectl delete -f deploy/deployment.yaml
kubectl delete -f deploy/auth.yaml
141 changes: 137 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,140 @@
## Amazon Eks Pod Identity Webhook
# Amazon EKS Pod Identity Webhook

Amazon EKS Pod Identity Webhook
This webhook is for mutating pods that will require AWS IAM access.

## License
## EKS Walkthrough

1. [Create an OIDC provider][1] in IAM for your cluster. You can find the OIDC
discovery endpoint by describing your EKS cluster.
```bash
aws eks describe-cluster --name $CLUSTER_NAME --query cluster.tokenDiscoveryEndpoint
```
And enter "sts.amazonaws.com" as the client-id
2. Create an IAM role for your pods and [modify the trust policy][2] to allow
your pod's service account to use the role:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::111122223333:oidc-provider/oidc.us-west-2.eks.amazonaws.com/624a142e-43fc-4a4e-9a65-0adbfe9d6a85"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
# scope the role to your cluster [required]
"oidc.us-west-2.eks.amazonaws.com/624a142e-43fc-4a4e-9a65-0adbfe9d6a85:aud": "sts.amazonaws.com",
# scope the role to the service account (optional)
"oidc.us-west-2.eks.amazonaws.com/624a142e-43fc-4a4e-9a65-0adbfe9d6a85:sub": "system:serviceaccount:default:my-serviceaccount"
},
# Optional for scoping to a namespace
"StringLike": {
"oidc.us-west-2.eks.amazonaws.com/624a142e-43fc-4a4e-9a65-0adbfe9d6a85:sub": "system:serviceaccount:default:*"
}
}
}
]
}
```
3. Modify your pod's service account to be annotated with the ARN of the role
you want the pod to use
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-serviceaccount
namespace: default
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::111122223333:role/s3-reader"
```
4. All new pod pods launched using this Service Account will be modified to use
IAM for pods. Below is an example pod spec with the environment variables and
volume fields added by the webhook.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
namespace: defaut
spec:
serviceAccountName: my-serviceaccount
containers:
- name: container-name
image: container-image:version
### Everything below is added by the webhook ###
env:
- name: AWS_IAM_ROLE_ARN
value: "arn:aws:iam::111122223333:role/s3-reader"
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: "/var/run/secrets/eks.amazonaws.com/serviceaccount/token"
volumeMounts:
- mountPath: "/var/run/secrets/eks.amazonaws.com/serviceaccount/"
name: aws-token
volumes:
- name: aws-token
projected:
sources:
- serviceAccountToken:
audience: "sts.amazonaws.com"
expirationSeconds: 86400
path: token
```

[1]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html
[2]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-idp_oidc.html

## Usage

```
Usage of amazon-eks-pod-identity-webhook:
--alsologtostderr log to standard error as well as files
--annotation-prefix string The Service Account annotation to look for (default "eks.amazonaws.com")
--cert-dir string (out-of-cluster) Directory to save certificates (default "/etc/webhook/certs")
--cert-duration duration (out-of-cluster) Lifetime for self-signed certificate (default 8760h0m0s)
--in-cluster Use in-cluster auth (default true)
--kube-api string (out-of-cluster) The url to the API server
--kubeconfig string (out-of-cluster) Absolute path to the API server kubeconfig file (default "~/.kube/config")
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--logtostderr log to standard error instead of files
--namespace string (in-cluster) The namespace name this webhook and the tls secret resides in (default "eks")
--port int Port to listen on (default 443)
--service-name string (in-cluster) The service name fronting this webhook (default "iam-for-pods")
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
--tls-secret string (in-cluster) The secret name for storing the TLS serving cert (default "iam-for-pods")
--token-audience string The default audience for tokens. Can be overridden by annotation (default "sts.amazonaws.com")
--token-expiration int The token expiration (default 86400)
--token-mount-path string The path to mount tokens (default "/var/run/secrets/eks.amazonaws.com/serviceaccount")
-v, --v Level log level for V logs
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
--webhook-config string (out-of-cluster) Path for where to write the webhook config file for the API server to consume (default "/etc/webhook/config.yaml")
```
## Installation
### In-cluster
This library is licensed under the Apache 2.0 License.
You can use the provided configuration files in the `deploy` directory, along with the provided `Makefile`
```
make cluster-up IMAGE=602401143452.dkr.ecr.us-west-2.amazonaws.com/eks/pod-identity-webhook:latest
```
This will:
* Create a service account, role, cluster-role, role-binding, and cluster-role-binding that will the deployment requires
* Create the deployment, service, and mutating webhook in the cluster
* Approve the CSR that the deployment created for its TLS serving certificate
### On API server
TODO
## Development
TODO
## Code of Conduct
TODO
## License
TODO
3 changes: 3 additions & 0 deletions bmg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"alias": "github.com/aws/amazon-eks-pod-identity-webhook"
}
76 changes: 76 additions & 0 deletions deploy/auth.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: iam-for-pods
namespace: eks
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: iam-for-pods
namespace: eks
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- update
- patch
resourceNames:
- "iam-for-pods"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: iam-for-pods
namespace: eks
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: iam-for-pods
subjects:
- kind: ServiceAccount
name: iam-for-pods
namespace: eks
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: iam-for-pods
rules:
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests
verbs:
- create
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: iam-for-pods
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: iam-for-pods
subjects:
- kind: ServiceAccount
name: iam-for-pods
namespace: eks
36 changes: 36 additions & 0 deletions deploy/deployment-base.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: iam-for-pods
namespace: eks
spec:
replicas: 1
selector:
matchLabels:
app: iam-for-pods
template:
metadata:
labels:
app: iam-for-pods
spec:
serviceAccountName: iam-for-pods
containers:
- name: iam-for-pods
image: IMAGE
imagePullPolicy: Always
command:
- /webhook
- --in-cluster
- --namespace=eks
- --service-name=iam-for-pods
- --tls-secret=iam-for-pods
- --annotation-prefix=eks.amazonaws.com
- --token-audience=sts.amazonaws.com
- --logtostderr
volumeMounts:
- name: webhook-certs
mountPath: /var/run/app/certs
readOnly: false
volumes:
- name: webhook-certs
emptyDir: {}
Loading

0 comments on commit 0048675

Please sign in to comment.