diff --git a/samples/eks-cluster-prework/scripts/pw-script.sh b/samples/eks-cluster-prework/scripts/pw-script.sh new file mode 100644 index 0000000..b264164 --- /dev/null +++ b/samples/eks-cluster-prework/scripts/pw-script.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Install kubectl + +# we are installing the current version if you are on an older cluster you might need to change this. +curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" +# Install kubectl +install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl + +#============= INSERT YOUR PREWORK STEPS HERE ====================# +# We will create a simple script the point of the blog is to show that you CAN run pre-work on the cluster via CloudFormation +# so we are less concerned with the content of this script. + +# there are much better ways to manage secrets ;) +kubectl create secret generic db-user-pass \ + --from-literal=username=devuser \ + --from-literal=password='S!B\*d$zDsb=' \ + -- namespace $KUBE_NAMESPACE +kubectl describe secrets/db-user-pass \ No newline at end of file diff --git a/samples/eks-cluster-prework/templates/eks-cluster-prework.template.yaml b/samples/eks-cluster-prework/templates/eks-cluster-prework.template.yaml new file mode 100644 index 0000000..c1ca84f --- /dev/null +++ b/samples/eks-cluster-prework/templates/eks-cluster-prework.template.yaml @@ -0,0 +1,56 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: "Amazon EKS PreWork pattern Blog" +Parameters: + AccessCIDR: + Default: 0.0.0.0/0 + Type: String + JobName: + Type: String + Default: 'job-example' + PreworkScriptBucket: + Type: String + Default: 'aws-quickstart' + PreworkScriptObject: + Type: String + Default: 'quickstart-examples/samples/eks-cluster-prework/script/pw-script.sh' +Resources: + EKSStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: 'https://aws-quickstart.s3.amazonaws.com/quickstart-amazon-eks/templates/amazon-eks-entrypoint-new-vpc.template.yaml' + Parameters: + # QuickStart properties + QSS3BucketName: aws-quickstart + QSS3KeyPrefix: quickstart-amazon-eks/ + # Cluster properties + ProvisionBastionHost: Enabled + AccessCIDR: !Ref AccessCIDR + NodeInstanceType: t3.large + NumberOfNodes: 1 + MaxNumberOfNodes: 1 + GetOIDCProvider: + Type: Custom::GetOIDCProvider + Properties: + ServiceToken: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-quickstart-ResourceReader" + AwsCliCommand: !Sub "eks describe-cluster --name ${ClusterName} --query 'cluster.identity.oidc.{issuer:issuer}'" + IdField: 'issuer' + PreworkStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: 'https://aws-quickstart.s3.amazonaws.com/quickstart-examples/samples/eks-cluster-prework/templates/prework.template.yaml' + Parameters: + ClusterName: !Sub "EKSStack.Outputs.EKSClusterName" + PreworkScriptBucket: !Ref PreworkScriptBucket + PreworkScriptObject: !Ref PreworkScriptObject + JobName: !Ref JobName + KubernetesNameSpace: "prework-example" + OIDCProvider: !Sub + - "${OIDCProvider1}/${OIDCProvider2}/${OIDCProvider3}" + - OIDCProvider1: !Select [ 2, !Split [ "/", !Ref GetOIDCProvider ] ] + OIDCProvider2: !Select [ 3, !Split [ "/", !Ref GetOIDCProvider ] ] + OIDCProvider3: !Select [ 4, !Split [ "/", !Ref GetOIDCProvider ] ] +Outputs: + EKSClusterName: + Value: !GetAtt EKSStack.Outputs.EKSClusterName + BastionIP: + Value: !GetAtt EKSStack.Outputs.BastionIP diff --git a/samples/eks-cluster-prework/templates/prework.template.yaml b/samples/eks-cluster-prework/templates/prework.template.yaml new file mode 100644 index 0000000..aae7057 --- /dev/null +++ b/samples/eks-cluster-prework/templates/prework.template.yaml @@ -0,0 +1,187 @@ +AWSTemplateFormatVersion: "2010-09-09" +Description: "Amazon EKS cluster pre/post-work blog sample" +Parameters: + ClusterName: + Type: String + PreworkScriptBucket: + Type: String + Default: aws-quickstart + PreworkScriptObject: + Type: String + Default: "quickstart-examples/samples/eks-cluster-prework/scripts/pw-script.sh" + JobName: + Type: String + Default: job-example + AllowedPattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*' + ConstraintDescription: "a lowercase RFC 1123 subdomain must consist of lower case + alphanumeric characters, '-' or '.', and must start and end with an alphanumeric + character" + OIDCProvider: + Type: String + Description: Amazon EKS cluster OIDC provider, without the protocol (e.g., oidc.eks.us-east-1.amazonaws.com/id/SADFASFFASFXCCVXCVSDFSDF). + Default: "" + KubernetesNameSpace: + Type: String + Default: "prework-example" +Resources: + PreWorkIAMRole: + Type: AWS::IAM::Role + Properties: + RoleName: !Sub "pw-role-${JobName}" + AssumeRolePolicyDocument: !Sub + - | + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::${AWS::AccountId}:oidc-provider/${OIDCProvider}" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "${OIDCProvider}:sub": "system:serviceaccount:${NameSpace}:${ResourceName}" + } + } + } + ] + } + - NameSpace: !Ref KubernetesNameSpace + ResourceName: !Sub "pw-service-account-${JobName}" + Path: "/" + Policies: + - PolicyName: root + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - s3:GetObject + - s3:HeadObject + Resource: + - !Sub "arn:aws:s3:::${PreworkScriptBucket}/${PreworkScriptObject}" + KubePreWorkNamespace: + Type: "AWSQS::Kubernetes::Resource" + Properties: + ClusterName: !Ref ClusterName + Namespace: default + Manifest: !Sub | + kind: Namespace + apiVersion: v1 + metadata: + name: ${KubernetesNameSpace} + KubePreWorkRole: + Type: AWSQS::Kubernetes::Resource + DependsOn: [ KubePreWorkNamespace ] + Properties: + ClusterName: !Ref ClusterName + Namespace: !Ref KubernetesNameSpace + Manifest: !Sub + - | + apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + labels: + app.kubernetes.io/name: "${ResourceName}" + name: "${ResourceName}" + # Modify for your scripts here + rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - ResourceName: !Sub "pw-role-${JobName}" + NameSpace: !Ref "KubernetesNameSpace" + KubePreWorkServiceAccount: + Type: AWSQS::Kubernetes::Resource + DependsOn: [ KubePreWorkNamespace ] + Properties: + ClusterName: !Ref ClusterName + Namespace: !Ref KubernetesNameSpace + Manifest: !Sub + - | + apiVersion: v1 + kind: ServiceAccount + metadata: + labels: + app.kubernetes.io/name: "${ResourceName}" + annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::${AWS::AccountId}:role/${RoleName} + name: "${ResourceName}" + namespace: ${NameSpace} + - ResourceName: !Sub "pw-service-account-${JobName}" + NameSpace: !Ref KubernetesNameSpace + RoleName: !Ref PreWorkIAMRole + KubePreWorkRoleBinding: + Type: AWSQS::Kubernetes::Resource + DependsOn: [ KubePreWorkNamespace, KubePreWorkRole, KubePreWorkServiceAccount ] + Properties: + ClusterName: !Ref ClusterName + Namespace: !Ref KubernetesNameSpace + Manifest: !Sub + - | + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + labels: + app.kubernetes.io/name: "${ResourceName}" + name: "${ResourceName}" + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: "pw-role-${JobName}" + subjects: + - kind: ServiceAccount + name: "pw-service-account-${JobName}" + namespace: ${NameSpace} + - ResourceName: !Sub "pw-role-binding-${JobName}" + NameSpace: !Ref KubernetesNameSpace + KubePreWorkJob: + DependsOn: [ PreWorkIAMRole, KubePreWorkRole, KubePreWorkServiceAccount, KubePreWorkRoleBinding ] + Type: AWSQS::Kubernetes::Resource + Properties: + ClusterName: !Ref ClusterName + Namespace: !Ref KubernetesNameSpace + Manifest: !Sub + - | + apiVersion: batch/v1 + kind: Job + metadata: + name: "${ResourceName}" + namespace: ${NameSpace} + spec: + template: + spec: + containers: + - name: ${ResourceName} + image: amazonlinux:2 + command: ["/bin/bash","-c"] + args: + - > + sleep 15; + yum update -y; + yum install -y awscli; + export AWS_REGION=${AWS::Region}; + export NS=${NameSpace}; + aws sts get-caller-identity; + aws s3 cp ${!S3_SCRIPT_URL} ./prework-script.sh && + chmod +x ./prework-script.sh && + ./prework-script.sh + env: + - name: S3_SCRIPT_URL + value: ${S3ScriptURL} + - name: AWS_REGION + value: ${AWS::Region} + - name: KUBE_NAMESPACE + value: ${KubernetesNameSpace} + serviceAccountName: "pw-service-account-${JobName}" + restartPolicy: Never + backoffLimit: 4 + - ResourceName: !Sub "pw-job-${JobName}" + NameSpace: !Ref "KubernetesNameSpace" + S3ScriptURL: !Sub "s3://${PreworkScriptBucket}/${PreworkScriptObject}" \ No newline at end of file