Skip to content

Instantly share code, notes, and snippets.

@amcginlay
Last active March 20, 2022 10:14
Show Gist options
  • Save amcginlay/edc3839774df8a4f027f8be20bd1d6b6 to your computer and use it in GitHub Desktop.
Save amcginlay/edc3839774df8a4f027f8be20bd1d6b6 to your computer and use it in GitHub Desktop.
cert-manager-eks.sh
#######################
# cert-manager/eks demo
#######################
# to start, complete everything up to and including:
# https://github.com/amcginlay/eks-demos/blob/main/doc/06-build-cluster/README.md
# create ROOT PCA
# set variables
#registered_domain=aws.orbocorbo.com
registered_domain=awsome.education
# install the aws load balancer controller
aws iam delete-policy --policy-arn arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy >/dev/null 2>&1
aws iam create-policy \
--policy-name AWSLoadBalancerControllerIAMPolicy \
--policy-document \
file://<(curl --silent iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.3.1/docs/install/iam_policy.json)
eksctl create iamserviceaccount \
--cluster=${EKS_CLUSTER_NAME} \
--namespace kube-system \
--name=aws-load-balancer-controller \
--attach-policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AWSLoadBalancerControllerIAMPolicy \
--override-existing-serviceaccounts \
--approve
helm repo add eks https://aws.github.io/eks-charts
helm -n kube-system install aws-load-balancer-controller eks/aws-load-balancer-controller \
--set clusterName=${EKS_CLUSTER_NAME} \
--set serviceAccount.create=false \
--set serviceAccount.name=aws-load-balancer-controller
# deploy cert-manager
kubectl create namespace cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.7.1/cert-manager.yaml
# install the AWS PCA Issuer plugin for cert-manager
PCA_ARN=$(aws acm-pca list-certificate-authorities --query "CertificateAuthorities[0].Arn" --output text)
aws iam delete-policy --policy-arn arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AWSPCAIssuerIAMPolicy >/dev/null 2>&1
aws iam create-policy \
--policy-name AWSPCAIssuerIAMPolicy \
--policy-document file://<(cat <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "awspcaissuer",
"Action": [
"acm-pca:DescribeCertificateAuthority",
"acm-pca:GetCertificate",
"acm-pca:IssueCertificate"
],
"Effect": "Allow",
"Resource": "${PCA_ARN}"
}
]
}
EOF
)
eksctl create iamserviceaccount \
--cluster=${EKS_CLUSTER_NAME} \
--namespace=aws-pca-issuer \
--name=aws-pca-issuer \
--attach-policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/AWSPCAIssuerIAMPolicy \
--override-existing-serviceaccounts \
--approve
helm repo add awspca https://cert-manager.github.io/aws-privateca-issuer
helm -n aws-pca-issuer install aws-pca-issuer awspca/aws-privateca-issuer --set serviceAccount.create=false --set serviceAccount.name=aws-pca-issuer
# confirm the aws-pca-issuer is ready
kubectl -n aws-pca-issuer get pods
# create the cluster issuer (NOTE this is a different Kind to the letsencrypt one)
cat <<EOF | tee ~/environment/01-aws-pca-cluster-issuer.yaml | kubectl apply -f -
apiVersion: awspca.cert-manager.io/v1beta1
kind: AWSPCAClusterIssuer
metadata:
name: aws-pca-cluster-issuer
spec:
arn: ${PCA_ARN}
region: ${AWS_DEFAULT_REGION}
EOF
# confirm the aws-pca-issuer has been verified
kubectl describe awspcaclusterissuer aws-pca-cluster-issuer
# create the NetworkLoadBalancer
kubectl create namespace dev
cat <<EOF | tee ~/environment/02-demo-service.yaml | kubectl -n dev apply -f -
apiVersion: v1
kind: Service
metadata:
name: demo-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb-ip"
service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
spec:
type: LoadBalancer
ports:
- port: 443
targetPort: 8443
protocol: TCP
name: https
selector:
app: demo-app
EOF
# grab the ELB DNS name - take it an add it as an A ALIAS record against you registered domain in Route53
sleep 10 && kubectl -n dev get service demo-service
# generate a backend certificate
cat <<EOF | tee ~/environment/03-demo-certificate.yaml | kubectl -n dev apply -f -
kind: Certificate
apiVersion: cert-manager.io/v1
metadata:
name: demo-certificate
spec:
commonName: ${registered_domain}
dnsNames:
- ${registered_domain}
duration: 2160h0m0s
issuerRef:
group: awspca.cert-manager.io
kind: AWSPCAClusterIssuer
name: aws-pca-cluster-issuer
renewBefore: 360h0m0s
secretName: demo-certificate-secret
usages:
- server auth
- client auth
privateKey:
algorithm: "RSA"
size: 2048
EOF
# confirm the certificate has been issued
kubectl -n dev describe certificate demo-certificate
# deploy your demo configmap and app
cat <<EOF | tee ~/environment/04-demo-config.yaml | kubectl -n dev apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: demo-config
data:
app.conf: |-
server {
listen 8443 ssl proxy_protocol;
real_ip_header proxy_protocol;
set_real_ip_from 192.168.0.0/16;
server_name ${registered_domain};
ssl_certificate /etc/nginx/ssl/tls.crt;
ssl_certificate_key /etc/nginx/ssl/tls.key;
default_type text/plain;
location / {
return 200 "hello from pod \$hostname\n";
}
}
EOF
cat <<EOF | tee ~/environment/05-demo-app.yaml | kubectl -n dev apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
spec:
replicas: 1
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: demo-app
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8443
volumeMounts:
- name: secret
mountPath: /etc/nginx/ssl
readOnly: true
- name: config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: secret
secret:
secretName: demo-certificate-secret # this was auto-generated by the certificate
- name: config-volume
configMap:
name: demo-config
EOF
# wait until dig util can resolve the NLB
echo ${registered_domain} # check and set as appropriate
watch dig ${registered_domain}
# verify end-to-end TLS encryption (use "GET /"" to hit endpoint or ctrl+c to quit)
openssl s_client -connect ${registered_domain}:443
# check local IP as this should be passed right through to the pod, then send in a curl request
curl http://checkip.amazonaws.com
curl --insecure https://${registered_domain}:443
# tail the logs to see the source IP is preserved
kubectl -n dev logs deploy/demo-app
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment