├── secrets
└── .gitignore
├── vars
├── dynamic
│ └── .gitignore
└── static
│ ├── custom_definitions.yaml.example
│ └── definitions.yaml
├── cloudformation
├── .DS_Store
├── eks-external-dns-iam.template.yaml
├── eks-cluster-autoscaler-iam.template.yaml
├── eks-storage-provider-ebscsi-iam.template.yaml
├── eks-container-insights-iam.template.yaml
├── eks-storage-provider-efscsi-iam.template.yaml
├── eks-storage-provider-efscsi-storage.template.yaml
├── eks-bastion.template.yaml
└── eks-loadbalancer-controller-iam-policy.template.yaml
├── .gitignore
├── docs
├── architecture
│ ├── EksExampleArchitectureDiagram.png
│ └── EksExampleArchitectureDiagram.drawio
└── examples
│ ├── k8s
│ └── microservice-example
│ │ ├── microservice-example-crystal-service.manifest.yaml
│ │ ├── microservice-example-nodejs-service.manifest.yaml
│ │ ├── microservice-example-frontend-service.manifest.yaml
│ │ ├── microservice-example-hpa.manifest.yaml
│ │ ├── microservice-example-nodejs-deployment.manifest.yaml
│ │ ├── microservice-example-crystal-deployment.manifest.yaml
│ │ ├── microservice-example-frontend-ingress.manifest.yaml
│ │ └── microservice-example-frontend-deployment.manifest.yaml
│ ├── deploy-examples.playbook.yaml
│ ├── tasks
│ └── microservice-example.task.yaml
│ └── destroy-examples.playbook.yaml
├── CODE_OF_CONDUCT.md
├── .github
└── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── tasks
├── eks-metrics-server.task.yaml
├── bastion.task.yaml
├── eks-external-dns.task.yaml
├── eks-cluster-autoscaler.task.yaml
├── eks-loadbalancer-controller.task.yaml
├── eks-xray.task.yaml
├── eks-cluster.task.yaml
├── eks-container-insights.task.yaml
├── acm.task.yaml
├── eks-storage-provider-ebscsi.task.yaml
└── eks-storage-provider-efscsi.task.yaml
├── ansible.cfg
├── LICENSE.md
├── eks-deploy-cluster.playbook.yaml
├── CONTRIBUTING.MD
├── eks-destroy-cluster.playbook.yaml
└── README.MD
/secrets/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
--------------------------------------------------------------------------------
/vars/dynamic/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore everything in this directory
2 | *
3 | # Except this file
4 | !.gitignore
--------------------------------------------------------------------------------
/cloudformation/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-amazon-eks-ansible-example/HEAD/cloudformation/.DS_Store
--------------------------------------------------------------------------------
/vars/static/custom_definitions.yaml.example:
--------------------------------------------------------------------------------
1 | eksexample_hostedzoneid: HOSTEDZONEID
2 | eksexample_hostedzonename: DOMAINNAME
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | secrets/*
2 | vars/eksexample_*
3 | vars/*/eksexample_*
4 | vars/static/custom_definitions.yaml
5 | ansible.log
6 | .vscode
7 | .DS_Store
--------------------------------------------------------------------------------
/docs/architecture/EksExampleArchitectureDiagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-amazon-eks-ansible-example/HEAD/docs/architecture/EksExampleArchitectureDiagram.png
--------------------------------------------------------------------------------
/docs/examples/k8s/microservice-example/microservice-example-crystal-service.manifest.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: eksdemo-crystal
5 | namespace: eksdemo
6 | spec:
7 | ports:
8 | - port: 80
9 | targetPort: 3000
10 | protocol: TCP
11 | selector:
12 | app: eksdemo-crystal
--------------------------------------------------------------------------------
/docs/examples/k8s/microservice-example/microservice-example-nodejs-service.manifest.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: eksdemo-nodejs
5 | namespace: eksdemo
6 | spec:
7 | ports:
8 | - port: 80
9 | targetPort: 3000
10 | protocol: TCP
11 | selector:
12 | app: eksdemo-nodejs
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4 | opensource-codeofconduct@amazon.com with any additional questions or comments.
5 |
--------------------------------------------------------------------------------
/docs/examples/k8s/microservice-example/microservice-example-frontend-service.manifest.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: eksdemo-frontend
5 | namespace: eksdemo
6 | spec:
7 | type: NodePort
8 | ports:
9 | - port: 80
10 | targetPort: 3000
11 | protocol: TCP
12 | selector:
13 | app: eksdemo-frontend
--------------------------------------------------------------------------------
/docs/examples/k8s/microservice-example/microservice-example-hpa.manifest.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: autoscaling/v1
2 | kind: HorizontalPodAutoscaler
3 | metadata:
4 | name: {{ item }}
5 | namespace: eksdemo
6 | spec:
7 | maxReplicas: 10
8 | minReplicas: 2
9 | scaleTargetRef:
10 | apiVersion: apps/v1
11 | kind: Deployment
12 | name: {{ item }}
13 | targetCPUUtilizationPercentage: 30
--------------------------------------------------------------------------------
/vars/static/definitions.yaml:
--------------------------------------------------------------------------------
1 | eksexample_region: eu-central-1
2 | eksexample_worker_desiredcount: 2
3 | eksexample_worker_maxcount: 10
4 | eksexample_worker_mincount: 2
5 | eksexample_worker_instancetype: t3a.medium
6 | eksexample_bastion_instancetype: t3a.small
7 | eksexample_clustername: ansible-eks-testcluster
8 | eksexample_clusterversion: 1.23
9 | eksexample_aws_profilename: ansible
10 | eksexample_aws_profilename: suredavi+ansible-admins
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/docs/examples/k8s/microservice-example/microservice-example-nodejs-deployment.manifest.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: eksdemo-nodejs
5 | labels:
6 | app: eksdemo-nodejs
7 | namespace: eksdemo
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: eksdemo-nodejs
13 | strategy:
14 | rollingUpdate:
15 | maxSurge: 25%
16 | maxUnavailable: 25%
17 | type: RollingUpdate
18 | template:
19 | metadata:
20 | labels:
21 | app: eksdemo-nodejs
22 | spec:
23 | containers:
24 | - image: brentley/ecsdemo-nodejs:latest
25 | imagePullPolicy: Always
26 | name: eksdemo-nodejs
27 | ports:
28 | - containerPort: 3000
29 | protocol: TCP
30 | resources:
31 | limits:
32 | cpu: 0.1
33 | requests:
34 | cpu: 0.1
--------------------------------------------------------------------------------
/tasks/eks-metrics-server.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | # Download and apply manifest
8 | - name: Download metrics-server manifest to the cluster.
9 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
10 | ansible.builtin.get_url:
11 | url: https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
12 | dest: ~/metrics-server.yaml
13 | mode: '0664'
14 |
15 | - name: Apply metrics-server manifest to the cluster.
16 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
17 | kubernetes.core.k8s:
18 | state: present
19 | src: ~/metrics-server.yaml
--------------------------------------------------------------------------------
/docs/examples/k8s/microservice-example/microservice-example-crystal-deployment.manifest.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: eksdemo-crystal
5 | labels:
6 | app: eksdemo-crystal
7 | namespace: eksdemo
8 | spec:
9 | replicas: 1
10 | selector:
11 | matchLabels:
12 | app: eksdemo-crystal
13 | strategy:
14 | rollingUpdate:
15 | maxSurge: 25%
16 | maxUnavailable: 25%
17 | type: RollingUpdate
18 | template:
19 | metadata:
20 | labels:
21 | app: eksdemo-crystal
22 | spec:
23 | containers:
24 | - image: brentley/ecsdemo-crystal:latest
25 | imagePullPolicy: Always
26 | name: eksdemo-crystal
27 | ports:
28 | - containerPort: 3000
29 | protocol: TCP
30 | resources:
31 | limits:
32 | cpu: 0.1
33 | requests:
34 | cpu: 0.1
--------------------------------------------------------------------------------
/ansible.cfg:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | [defaults]
8 | host_key_checking = False
9 | fork = 5
10 | gathering = smart
11 | fact_caching = jsonfile
12 | fact_caching_connection = /tmp/cache
13 | fact_caching_timeout = 600
14 | nocows = 1
15 | timeout = 60
16 | retry_files_enabled = False
17 | callback_whitelist = profile_tasks
18 | stdout_callback = skippy
19 | log_path = ./ansible.log
20 | become = false
21 | interpreter_python = auto
22 | executable = /bin/bash
23 |
24 | [ssh_connection]
25 | ssh_args = -o ControlMaster=auto -o ControlPersist=30m -o ServerAliveInterval=10 -o IdentitiesOnly=yes
26 | control_path = ~/.ssh/ansible-%%r@%%h:%%p
27 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this
4 | software and associated documentation files (the "Software"), to deal in the Software
5 | without restriction, including without limitation the rights to use, copy, modify,
6 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
7 | permit persons to whom the Software is furnished to do so.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
10 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
11 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
12 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
13 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
14 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/docs/examples/k8s/microservice-example/microservice-example-frontend-ingress.manifest.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.k8s.io/v1
2 | kind: Ingress
3 | metadata:
4 | name: eksdemo-frontend
5 | namespace: eksdemo
6 | annotations:
7 | kubernetes.io/ingress.class: alb
8 | alb.ingress.kubernetes.io/scheme: internet-facing
9 | alb.ingress.kubernetes.io/certificate-arn: "{{ eksexamplesslarn }}"
10 | external-dns.alpha.kubernetes.io/hostname: eksdemo."{{ eksexample_hostedzonename }}"
11 | alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]'
12 | alb.ingress.kubernetes.io/target-type: ip
13 | alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
14 | spec:
15 | rules:
16 | - http:
17 | paths:
18 | - path: /
19 | pathType: Prefix
20 | backend:
21 | service:
22 | name: eksdemo-frontend
23 | port:
24 | number: 80
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/cloudformation/eks-external-dns-iam.template.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | AWSTemplateFormatVersion: "2010-09-09"
8 | Resources:
9 |
10 | EKSExternalDNSPolicy:
11 | Type: 'AWS::IAM::ManagedPolicy'
12 | Properties:
13 | ManagedPolicyName: EKSExternalDNSPolicy
14 | PolicyDocument:
15 | Version: 2012-10-17
16 | Statement:
17 | - Effect: Allow
18 | Action:
19 | - route53:ChangeResourceRecordSets
20 | Resource:
21 | - arn:aws:route53:::hostedzone/*
22 | - Effect: Allow
23 | Action:
24 | - route53:ListHostedZones
25 | - route53:ListResourceRecordSets
26 | Resource:
27 | - "*"
--------------------------------------------------------------------------------
/docs/examples/k8s/microservice-example/microservice-example-frontend-deployment.manifest.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: eksdemo-frontend
5 | labels:
6 | app: eksdemo-fronten
7 | namespace: eksdemo
8 | spec:
9 | selector:
10 | matchLabels:
11 | app: eksdemo-frontend
12 | replicas: 2
13 | strategy:
14 | rollingUpdate:
15 | maxSurge: 25%
16 | maxUnavailable: 25%
17 | type: RollingUpdate
18 | template:
19 | metadata:
20 | labels:
21 | app: eksdemo-frontend
22 | spec:
23 | containers:
24 | - image: brentley/ecsdemo-frontend:latest
25 | imagePullPolicy: Always
26 | name: eksdemo-frontend
27 | ports:
28 | - containerPort: 3000
29 | protocol: TCP
30 | env:
31 | - name: CRYSTAL_URL
32 | value: "http://eksdemo-crystal.eksdemo.svc.cluster.local/crystal"
33 | - name: NODEJS_URL
34 | value: "http://eksdemo-nodejs.eksdemo.svc.cluster.local/"
35 | resources:
36 | limits:
37 | cpu: 0.2
38 | requests:
39 | cpu: 0.2
--------------------------------------------------------------------------------
/cloudformation/eks-cluster-autoscaler-iam.template.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | AWSTemplateFormatVersion: "2010-09-09"
8 | Resources:
9 |
10 | EKSClusterAutoscalerPolicy:
11 | Type: 'AWS::IAM::ManagedPolicy'
12 | Properties:
13 | ManagedPolicyName: EKSClusterAutoscalerPolicy
14 | PolicyDocument:
15 | Version: 2012-10-17
16 | Statement:
17 | - Effect: Allow
18 | Action:
19 | - autoscaling:DescribeAutoScalingGroups
20 | - autoscaling:DescribeAutoScalingInstances
21 | - autoscaling:DescribeLaunchConfigurations
22 | - autoscaling:DescribeTags
23 | - autoscaling:SetDesiredCapacity
24 | - autoscaling:TerminateInstanceInAutoScalingGroup
25 | - ec2:DescribeLaunchTemplateVersions
26 | Resource: '*'
--------------------------------------------------------------------------------
/cloudformation/eks-storage-provider-ebscsi-iam.template.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | AWSTemplateFormatVersion: "2010-09-09"
8 |
9 | Resources:
10 | EKSStorageProviderEBSCsiPolicy:
11 | Type: 'AWS::IAM::ManagedPolicy'
12 | Properties:
13 | ManagedPolicyName: EKSStorageProviderEBSCsiPolicy
14 | PolicyDocument:
15 | Version: 2012-10-17
16 | Statement:
17 | - Effect: Allow
18 | Action:
19 | - ec2:AttachVolume
20 | - ec2:CreateSnapshot
21 | - ec2:CreateTags
22 | - ec2:CreateVolume
23 | - ec2:DeleteSnapshot
24 | - ec2:DeleteTags
25 | - ec2:DeleteVolume
26 | - ec2:DescribeInstances
27 | - ec2:DescribeSnapshots
28 | - ec2:DescribeTags
29 | - ec2:DescribeVolumes
30 | - ec2:DetachVolume
31 | Resource: '*'
--------------------------------------------------------------------------------
/cloudformation/eks-container-insights-iam.template.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | AWSTemplateFormatVersion: "2010-09-09"
8 | Parameters:
9 |
10 | nodegroupRoleName:
11 | Type: String
12 | Default: ""
13 |
14 | Resources:
15 |
16 | nodegroupContainerInsightsPolicy:
17 | Type: 'AWS::IAM::ManagedPolicy'
18 | Properties:
19 | Path: /
20 | PolicyDocument:
21 | Version: 2012-10-17
22 | Statement:
23 | - Effect: Allow
24 | Action:
25 | - cloudwatch:PutMetricData
26 | - ec2:DescribeVolumes
27 | - ec2:DescribeTags
28 | - logs:PutLogEvents
29 | - logs:DescribeLogStreams
30 | - logs:DescribeLogGroups
31 | - logs:CreateLogStream
32 | - logs:CreateLogGroup
33 | Resource: "*"
34 | - Effect: Allow
35 | Action:
36 | - ssm:GetParameter
37 | Resource: "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
38 | Roles:
39 | - !Ref nodegroupRoleName
--------------------------------------------------------------------------------
/cloudformation/eks-storage-provider-efscsi-iam.template.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | AWSTemplateFormatVersion: "2010-09-09"
8 |
9 | Resources:
10 | EKSStorageProviderEFSCsiPolicy:
11 | Type: 'AWS::IAM::ManagedPolicy'
12 | Properties:
13 | ManagedPolicyName: EKSStorageProviderEFSCsiPolicy
14 | PolicyDocument:
15 | Version: '2012-10-17'
16 | Statement:
17 | - Effect: Allow
18 | Action:
19 | - elasticfilesystem:DescribeAccessPoints
20 | - elasticfilesystem:DescribeFileSystems
21 | - elasticfilesystem:DescribeMountTargets
22 | - ec2:DescribeAvailabilityZones
23 | Resource: "*"
24 | - Effect: Allow
25 | Action:
26 | - elasticfilesystem:CreateAccessPoint
27 | Resource: "*"
28 | Condition:
29 | StringLike:
30 | aws:RequestTag/efs.csi.aws.com/cluster: 'true'
31 | - Effect: Allow
32 | Action: elasticfilesystem:DeleteAccessPoint
33 | Resource: "*"
34 | Condition:
35 | StringEquals:
36 | aws:ResourceTag/efs.csi.aws.com/cluster: 'true'
--------------------------------------------------------------------------------
/tasks/bastion.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: Create EC2 KeyPair
8 | ec2_key:
9 | profile: "{{ eksexample_aws_profilename }}"
10 | name: "{{ eksexample_clustername }}-keypair"
11 | region: "{{ eksexample_region }}"
12 | register: ec2_key_result
13 |
14 | - name: Save Private Key for Bastion Access
15 | copy: content="{{ ec2_key_result.key.private_key }}" dest="./secrets/id_rsa_eks" mode=0600
16 | when: ec2_key_result.changed
17 |
18 | - name: create bastion Environment
19 | cloudformation:
20 | profile: "{{ eksexample_aws_profilename }}"
21 | stack_name: "{{ eksexample_clustername }}-bastion"
22 | state: "present"
23 | region: "{{ eksexample_region }}"
24 | disable_rollback: false
25 | template_parameters:
26 | EKSBastionInstanceType: "{{ eksexample_bastion_instancetype }}"
27 | EKSBastionKeyPairName: "{{ eksexample_clustername }}-keypair"
28 | template: "./cloudformation/eks-bastion.template.yaml"
29 | register: bastion_informations
30 |
31 | - name: save outputs to local file for ref
32 | copy:
33 | content: "{{ bastion_informations.stack_outputs | to_nice_yaml }}"
34 | dest: ./vars/dynamic/eksexample_bastion.yaml
--------------------------------------------------------------------------------
/docs/examples/deploy-examples.playbook.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: Setup Kubernetes Example Deployments
8 | hosts: localhost
9 | gather_facts: no
10 |
11 | vars:
12 | ansible_ssh_private_key_file: "./secrets/id_rsa_eks"
13 | ansible_user: ec2-user
14 |
15 | tasks:
16 | - name: check ansible version
17 | when: (ansible_version.major == 2 and ansible_version.minor < 10 ) or (ansible_version.major < 2)
18 | run_once: yes
19 | fail:
20 | msg: Please use Ansible 2.10 or newer
21 |
22 | - name: import static var data
23 | include_vars:
24 | dir: ../../vars/static
25 | ignore_unknown_extensions: True
26 | extensions:
27 | - yaml
28 |
29 | - name: import dynamic var data
30 | include_vars:
31 | dir: ../../vars/dynamic
32 | ignore_unknown_extensions: True
33 | extensions:
34 | - yaml
35 |
36 | - name: Get AWS Account Information
37 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
38 | aws_caller_info:
39 | register: caller_info
40 |
41 | - name: setup kube services
42 | include_tasks: "{{ item }}"
43 | loop:
44 | - ./tasks/microservice-example.task.yaml
--------------------------------------------------------------------------------
/docs/examples/tasks/microservice-example.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: create eksdemo namespace
8 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
9 | kubernetes.core.k8s:
10 | state: present
11 | definition:
12 | apiVersion: v1
13 | kind: Namespace
14 | metadata:
15 | name: eksdemo
16 |
17 | - name: create eksdemo deployment
18 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
19 | kubernetes.core.k8s:
20 | state: present
21 | apply: yes
22 | definition: "{{ lookup('template', './k8s/microservice-example/microservice-example-{{ item }}.manifest.yaml') | from_yaml }}"
23 | loop:
24 | - nodejs-deployment
25 | - crystal-deployment
26 | - frontend-deployment
27 | - nodejs-service
28 | - crystal-service
29 | - frontend-service
30 | - frontend-ingress
31 |
32 | - name: create eksdemo horizontal scaling
33 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
34 | kubernetes.core.k8s:
35 | state: present
36 | apply: yes
37 | definition: "{{ lookup('template', './k8s/microservice-example/microservice-example-hpa.manifest.yaml') | from_yaml }}"
38 | loop:
39 | - eksdemo-nodejs
40 | - eksdemo-crystal
41 | - eksdemo-frontend
--------------------------------------------------------------------------------
/tasks/eks-external-dns.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: create Roles and Policies for cluster-autoscaler
8 | cloudformation:
9 | profile: "{{ eksexample_aws_profilename }}"
10 | stack_name: "{{ eksexample_clustername }}-external-dns-policy"
11 | state: present
12 | region: "{{ eksexample_region }}"
13 | template: "./cloudformation/eks-external-dns-iam.template.yaml"
14 |
15 | - name: setup service account for external-dns
16 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
17 | shell: >
18 | eksctl create iamserviceaccount \
19 | --name external-dns \
20 | --namespace kube-system \
21 | --cluster "{{ eksexample_clustername }}" \
22 | --attach-policy-arn "arn:aws:iam::{{ caller_info.account }}:policy/EKSExternalDNSPolicy" \
23 | --approve \
24 | --region {{ eksexample_region }} \
25 | --override-existing-serviceaccounts
26 |
27 | - name: add the external-dns helm repo
28 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
29 | kubernetes.core.helm_repository:
30 | name: external-dns
31 | repo_url: "https://kubernetes-sigs.github.io/external-dns/"
32 |
33 | - name: Deploy latest version of the external-dns chart inside kube-system namespace
34 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
35 | kubernetes.core.helm:
36 | name: external-dns
37 | chart_ref: external-dns/external-dns
38 | release_namespace: kube-system
39 | values:
40 | serviceAccount:
41 | create: false
42 | name: external-dns
--------------------------------------------------------------------------------
/tasks/eks-cluster-autoscaler.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: create Policies for cluster-autoscaler
8 | cloudformation:
9 | profile: "{{ eksexample_aws_profilename }}"
10 | stack_name: "{{ eksexample_clustername }}-cluster-autoscaler-policy"
11 | state: present
12 | region: "{{ eksexample_region }}"
13 | template: "./cloudformation/eks-cluster-autoscaler-iam.template.yaml"
14 |
15 | - name: setup service account for cluster-autoscaler
16 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
17 | shell: >
18 | eksctl create iamserviceaccount \
19 | --name cluster-autoscaler \
20 | --namespace kube-system \
21 | --cluster "{{ eksexample_clustername }}" \
22 | --attach-policy-arn "arn:aws:iam::{{ caller_info.account }}:policy/EKSClusterAutoscalerPolicy" \
23 | --approve \
24 | --region {{ eksexample_region }} \
25 | --override-existing-serviceaccounts
26 |
27 | - name: add the cluster-autoscaler helm repo
28 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
29 | kubernetes.core.helm_repository:
30 | name: autoscaler
31 | repo_url: "https://kubernetes.github.io/autoscaler"
32 |
33 | - name: Deploy latest version of the cluster-autoscaler chart inside kube-system namespace
34 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
35 | kubernetes.core.helm:
36 | name: cluster-autoscaler
37 | chart_ref: autoscaler/cluster-autoscaler
38 | release_namespace: kube-system
39 | values:
40 | clusterName: "{{ eksexample_clustername }}"
41 | serviceAccount:
42 | create: false
43 | name: cluster-autoscaler
--------------------------------------------------------------------------------
/docs/examples/destroy-examples.playbook.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: Destroy Amazon EKS example deployments
8 | hosts: localhost
9 | gather_facts: no
10 |
11 | vars:
12 | ansible_ssh_private_key_file: "./secrets/id_rsa_eks"
13 | ansible_user: ec2-user
14 |
15 | vars_prompt:
16 | - name: "security_check"
17 | prompt: "Do really want to DESTROY your example deployment (yes/no)?"
18 | private: no
19 |
20 | tasks:
21 | - name: check if we're gonna destroy
22 | when: not security_check | bool
23 | fail:
24 | msg: cancelled
25 |
26 | - name: check ansible version
27 | when: (ansible_version.major == 2 and ansible_version.minor < 10 ) or (ansible_version.major < 2)
28 | run_once: yes
29 | fail:
30 | msg: Please use Ansible 2.10 or newer
31 |
32 | - name: import static var data
33 | include_vars:
34 | dir: ../../vars/static
35 | ignore_unknown_extensions: True
36 | extensions:
37 | - yaml
38 |
39 | - name: import dynamic var data
40 | include_vars:
41 | dir: ../../vars/dynamic
42 | ignore_unknown_extensions: True
43 | extensions:
44 | - yaml
45 |
46 | - name: Get AWS Account Information
47 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
48 | aws_caller_info:
49 | register: caller_info
50 |
51 | - name: delete eksdemo namespace
52 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
53 | kubernetes.core.k8s:
54 | state: absent
55 | definition:
56 | apiVersion: v1
57 | kind: Namespace
58 | metadata:
59 | name: eksdemo
--------------------------------------------------------------------------------
/tasks/eks-loadbalancer-controller.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: create Policies for loadbalancer-controller
8 | cloudformation:
9 | profile: "{{ eksexample_aws_profilename }}"
10 | stack_name: "{{ eksexample_clustername }}-cluster-loadbalancercontroller-policy"
11 | state: present
12 | region: "{{ eksexample_region }}"
13 | template: "./cloudformation/eks-loadbalancer-controller-iam-policy.template.yaml"
14 |
15 | - name: setup service account for loadbalancer-controller
16 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
17 | shell: >
18 | eksctl create iamserviceaccount \
19 | --name aws-load-balancer-controller \
20 | --namespace kube-system \
21 | --cluster "{{ eksexample_clustername }}" \
22 | --attach-policy-arn "arn:aws:iam::{{ caller_info.account }}:policy/EKSloadbalancerControllerPolicy" \
23 | --approve \
24 | --region {{ eksexample_region }} \
25 | --override-existing-serviceaccounts
26 |
27 | - name: add the AWS Loadbalancer Controller helm repo
28 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
29 | kubernetes.core.helm_repository:
30 | name: aws-load-balancer-controller
31 | repo_url: "https://aws.github.io/eks-charts"
32 |
33 | - name: Deploy latest version of AWS Loadbalancer Controller chart inside kube-system namespace
34 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
35 | kubernetes.core.helm:
36 | name: aws-load-balancer-controller
37 | chart_ref: aws-load-balancer-controller/aws-load-balancer-controller
38 | release_namespace: kube-system
39 | values:
40 | clusterName: "{{ eksexample_clustername }}"
41 | serviceAccount:
42 | create: false
43 | name: aws-load-balancer-controller
--------------------------------------------------------------------------------
/tasks/eks-xray.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: setup service account for x-ray
8 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
9 | shell: >
10 | eksctl create iamserviceaccount \
11 | --name xray-daemon \
12 | --namespace kube-system \
13 | --cluster "{{ eksexample_clustername }}" \
14 | --attach-policy-arn arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess \
15 | --approve \
16 | --region {{ eksexample_region }} \
17 | --override-existing-serviceaccounts
18 |
19 | - name: label the xray service-account
20 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
21 | shell: >
22 | kubectl label serviceaccount xray-daemon app=xray-daemon -n kube-system --overwrite
23 |
24 | - name: Download cloudwatch insights manifests to the cluster.
25 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
26 | ansible.builtin.get_url:
27 | url: https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/master/k8s-deployment-manifest-templates/deployment-mode/daemonset/cwagent-fluentd-xray/cwagent-fluentd-xray-quickstart.yaml
28 | dest: ~/cwagent-fluentd-xray-quickstart.yaml
29 | mode: '0664'
30 |
31 |
32 | - name: Replace variables with values
33 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
34 | ansible.builtin.replace:
35 | path: ~/cwagent-fluentd-xray-quickstart.yaml
36 | regexp: "{{ item.key }}"
37 | replace: "{{ item.value }}"
38 | loop: "{{ replace_data | dict2items }}"
39 | vars:
40 | replace_data:
41 | '\{\{cluster_name\}\}': "'{{ eksexample_clustername }}'"
42 | '\{\{region_name\}\}': "'{{ eksexample_region }}'"
43 |
44 | - name: Apply the container insights manifest to the cluster.
45 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
46 | kubernetes.core.k8s:
47 | state: present
48 | src: ~/cwagent-fluentd-xray-quickstart.yaml
--------------------------------------------------------------------------------
/tasks/eks-cluster.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: check if eks cluster setup
8 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
9 | shell: eksctl get cluster --region {{ eksexample_region }} --verbose 0
10 | register: eks_check_output
11 | retries: 20
12 | delay: 10
13 | until: "eks_check_output is not failed"
14 |
15 | - name: create the eks cluster
16 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
17 | shell: >
18 | eksctl create cluster \
19 | --name {{ eksexample_clustername }} \
20 | --version {{ eksexample_clusterversion }} \
21 | --region {{ eksexample_region }} \
22 | --nodegroup-name {{ eksexample_clustername }}-linux-nodes \
23 | --node-type {{ eksexample_worker_instancetype }} \
24 | --nodes-min {{ eksexample_worker_mincount }} \
25 | --nodes-max {{ eksexample_worker_maxcount }} \
26 | --managed
27 | when: eks_check_output.stdout == "No clusters found"
28 |
29 | - name: write the kube config
30 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
31 | shell: >
32 | eksctl utils write-kubeconfig \
33 | --cluster {{ eksexample_clustername }} \
34 | --region {{ eksexample_region }}
35 | when: not eks_check_output.stdout == "No clusters found"
36 |
37 | - name: add the oidc provider for iam
38 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
39 | shell: >
40 | eksctl utils associate-iam-oidc-provider \
41 | --cluster {{ eksexample_clustername }} \
42 | --region {{ eksexample_region }} \
43 | --approve
44 | when: eks_check_output.stdout == "No clusters found"
45 |
46 | - name: enable cloudwatch logging
47 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
48 | shell: >
49 | eksctl utils update-cluster-logging \
50 | --cluster {{ eksexample_clustername }} \
51 | --enable-types all \
52 | --approve \
53 | --region {{ eksexample_region }}
54 | when: eks_check_output.stdout == "No clusters found"
55 |
--------------------------------------------------------------------------------
/cloudformation/eks-storage-provider-efscsi-storage.template.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | AWSTemplateFormatVersion: "2010-09-09"
8 | Parameters:
9 |
10 | Ekscidrblock:
11 | Type: String
12 | Default: ""
13 | Ekssubnetids:
14 | Type: CommaDelimitedList
15 | Default: ""
16 | Eksvpcid:
17 | Type: String
18 | Default: ""
19 |
20 | Resources:
21 |
22 | EksStorageProviderEfscsiSecurityGroup:
23 | Type: AWS::EC2::SecurityGroup
24 | Properties:
25 | VpcId: !Ref Eksvpcid
26 | GroupDescription: Security group for the Shared Storage
27 |
28 | EksStorageProviderEfscsiSecurityGroupApplicationPort:
29 | Type: AWS::EC2::SecurityGroupIngress
30 | Properties:
31 | CidrIp: !Ref Ekscidrblock
32 | IpProtocol: tcp
33 | FromPort: 2049
34 | ToPort: 2049
35 | GroupId: !Ref EksStorageProviderEfscsiSecurityGroup
36 |
37 | EksStorageProviderEfscsiFS:
38 | Type: AWS::EFS::FileSystem
39 | Properties:
40 | Encrypted: true
41 |
42 | EksStorageProviderEfscsiMountTarget1:
43 | Type: AWS::EFS::MountTarget
44 | Properties:
45 | FileSystemId:
46 | Ref: EksStorageProviderEfscsiFS
47 | SubnetId: !Select [0, !Ref Ekssubnetids]
48 | SecurityGroups:
49 | - !Ref EksStorageProviderEfscsiSecurityGroup
50 |
51 | EksStorageProviderEfscsiMountTarget2:
52 | Type: AWS::EFS::MountTarget
53 | Properties:
54 | FileSystemId:
55 | Ref: EksStorageProviderEfscsiFS
56 | SubnetId: !Select [1, !Ref Ekssubnetids]
57 | SecurityGroups:
58 | - !Ref EksStorageProviderEfscsiSecurityGroup
59 |
60 | EksStorageProviderEfscsiMountTarget3:
61 | Type: AWS::EFS::MountTarget
62 | Properties:
63 | FileSystemId:
64 | Ref: EksStorageProviderEfscsiFS
65 | SubnetId: !Select [2, !Ref Ekssubnetids]
66 | SecurityGroups:
67 | - !Ref EksStorageProviderEfscsiSecurityGroup
68 | Outputs:
69 | EksStorageProviderEfscsiFS:
70 | Value: !Ref EksStorageProviderEfscsiFS
71 | Description: Reference to the created Amazon EFS Volume
--------------------------------------------------------------------------------
/eks-deploy-cluster.playbook.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: Setup and Customize Amazon EKS
8 | hosts: localhost
9 | gather_facts: no
10 |
11 | vars:
12 | ansible_ssh_private_key_file: "./secrets/id_rsa_eks"
13 | ansible_user: ec2-user
14 |
15 | tasks:
16 | - name: check ansible version
17 | when: (ansible_version.major == 2 and ansible_version.minor < 10 ) or (ansible_version.major < 2)
18 | run_once: yes
19 | fail:
20 | msg: Please use Ansible 2.10 or newer
21 |
22 | - name: import static var data
23 | include_vars:
24 | dir: vars/static
25 | ignore_unknown_extensions: True
26 | extensions:
27 | - yaml
28 |
29 | - name: setup bastion host
30 | include_tasks: ./tasks/bastion.task.yaml
31 |
32 | - name: import dynamic var data
33 | include_vars:
34 | dir: vars/dynamic
35 | ignore_unknown_extensions: True
36 | extensions:
37 | - yaml
38 |
39 | - name: wait for the bastion to be booted and bootstraped (first-start)
40 | wait_for:
41 | host: "{{ EKSBastionInstancePublicIP }}"
42 | port: 22
43 | timeout: 300
44 | delay: 120
45 | when: bastion_informations.changed
46 |
47 | - name: Get AWS Account Information
48 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
49 | aws_caller_info:
50 | register: caller_info
51 | retries: 20
52 | delay: 10
53 | until: "caller_info is not failed"
54 |
55 | - name: setup the EKS Cluster and additional extensions of the cluster infrastructure
56 | include_tasks: "{{ item }}"
57 | loop:
58 | - ./tasks/eks-cluster.task.yaml
59 | - ./tasks/eks-storage-provider-ebscsi.task.yaml
60 | - ./tasks/eks-storage-provider-efscsi.task.yaml
61 | - ./tasks/eks-container-insights.task.yaml
62 | - ./tasks/eks-cluster-autoscaler.task.yaml
63 | - ./tasks/eks-loadbalancer-controller.task.yaml
64 | - ./tasks/eks-external-dns.task.yaml
65 | - ./tasks/eks-metrics-server.task.yaml
66 | - ./tasks/eks-xray.task.yaml
67 | - ./tasks/acm.task.yaml
--------------------------------------------------------------------------------
/tasks/eks-container-insights.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: create amazon-cloudwatch namespace
8 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
9 | kubernetes.core.k8s:
10 | state: present
11 | definition:
12 | apiVersion: v1
13 | kind: Namespace
14 | metadata:
15 | name: amazon-cloudwatch
16 |
17 | - name: get notegroups rolename
18 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
19 | shell: >
20 | aws cloudformation describe-stack-resources --region {{ eksexample_region }} --stack-name eksctl-{{ eksexample_clustername }}-nodegroup-{{ eksexample_clustername }}-linux-nodes \
21 | | jq -r '.StackResources[] | select(.ResourceType=="AWS::IAM::Role") | .PhysicalResourceId'
22 | register: eks_nodegroup_role_name
23 |
24 | - name: create Roles and Policies for container insights
25 | cloudformation:
26 | profile: "{{ eksexample_aws_profilename }}"
27 | stack_name: "{{ eksexample_clustername }}-container-insights-policy"
28 | state: present
29 | region: "{{ eksexample_region }}"
30 | template: "./cloudformation/eks-container-insights-iam.template.yaml"
31 | template_parameters:
32 | nodegroupRoleName: "{{ eks_nodegroup_role_name.stdout }}"
33 |
34 | - name: Download cloudwatch insights manifests to the cluster.
35 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
36 | ansible.builtin.get_url:
37 | url: https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluent-bit-quickstart.yaml
38 | dest: ~/cwagent-fluent-bit-quickstart.yaml
39 | mode: '0664'
40 |
41 | - name: Replace variables with values
42 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
43 | ansible.builtin.replace:
44 | path: ~/cwagent-fluent-bit-quickstart.yaml
45 | regexp: "{{ item.key }}"
46 | replace: "{{ item.value }}"
47 | loop: "{{ replace_data | dict2items }}"
48 | vars:
49 | replace_data:
50 | '\{\{cluster_name\}\}': "'{{ eksexample_clustername }}'"
51 | '\{\{region_name\}\}': "'{{ eksexample_region }}'"
52 | '\{\{http_server_toggle\}\}': "'On'"
53 | '\{\{read_from_tail\}\}': "'On'"
54 | '\{\{read_from_head\}\}': "'Off'"
55 | '\{\{http_server_port\}\}': "'2020'"
56 |
57 | - name: Apply the container insights manifest to the cluster.
58 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
59 | kubernetes.core.k8s:
60 | state: present
61 | src: ~/cwagent-fluent-bit-quickstart.yaml
--------------------------------------------------------------------------------
/tasks/acm.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: check if cert already existing on ACM
8 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
9 | shell: >
10 | aws acm list-certificates --region {{ eksexample_region }} \
11 | | jq -r '.CertificateSummaryList | .[] | select (.DomainName == "{{ eksexample_hostedzonename }}").DomainName'
12 | register: cert_existing
13 |
14 | - name: request wildcard SSL Cert on ACM
15 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
16 | shell: >
17 | aws acm request-certificate --domain-name {{ eksexample_hostedzonename }} \
18 | --subject-alternative-names *.{{ eksexample_hostedzonename }} --validation-method DNS \
19 | --query CertificateArn --region {{ eksexample_region }} --output text
20 | when: cert_existing.stdout == ""
21 |
22 | - name: get cert arn on ACM
23 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
24 | shell: >
25 | aws acm list-certificates --region {{ eksexample_region }} \
26 | | jq -r '.CertificateSummaryList | .[] | select (.DomainName == "{{ eksexample_hostedzonename }}").CertificateArn'
27 | register: cert_arn
28 |
29 | - name: waiting some seconds cause of AWS ACM latency
30 | pause:
31 | seconds: 20
32 |
33 | - name: read ssl cert name
34 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
35 | shell: >
36 | aws acm describe-certificate --region {{ eksexample_region }} \
37 | --certificate-arn {{ cert_arn.stdout }} \
38 | --query Certificate.DomainValidationOptions[0].ResourceRecord.Name \
39 | --output text
40 | register: ssl_cert_name
41 |
42 | - name: read ssl cert value
43 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
44 | shell: >
45 | aws acm describe-certificate --region {{ eksexample_region }} \
46 | --certificate-arn {{ cert_arn.stdout }} \
47 | --query Certificate.DomainValidationOptions[0].ResourceRecord.Value \
48 | --output text
49 | register: ssl_cert_value
50 |
51 | - name : create validation record set in route53
52 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
53 | route53:
54 | state: present
55 | zone: "{{ eksexample_hostedzonename }}"
56 | record: "{{ ssl_cert_name.stdout }}"
57 | type: CNAME
58 | ttl: 60
59 | value: "{{ ssl_cert_value.stdout }}"
60 | wait: yes
61 | overwrite: 'true'
62 |
63 | - name: wait for cert validation
64 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
65 | shell: >
66 | aws acm wait certificate-validated --region {{ eksexample_region }} --certificate-arn "{{ cert_arn.stdout }}"
67 |
68 | - name: save SSL creation outputs to local file for ref
69 | copy:
70 | content: "eksexamplesslarn: {{ cert_arn.stdout }}"
71 | dest: ./vars/dynamic/eksexample_ssl.yaml
--------------------------------------------------------------------------------
/tasks/eks-storage-provider-ebscsi.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: create Roles and Policies for ebs csi
8 | cloudformation:
9 | profile: "{{ eksexample_aws_profilename }}"
10 | stack_name: "{{ eksexample_clustername }}-storage-provider-ebscsi-policy"
11 | state: present
12 | region: "{{ eksexample_region }}"
13 | template: "./cloudformation/eks-storage-provider-ebscsi-iam.template.yaml"
14 |
15 | - name: setup service account for ebs csi controller
16 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
17 | shell: >
18 | eksctl create iamserviceaccount \
19 | --name ebs-csi-controller-sa \
20 | --namespace kube-system \
21 | --cluster "{{ eksexample_clustername }}" \
22 | --attach-policy-arn "arn:aws:iam::{{ caller_info.account }}:policy/EKSStorageProviderEBSCsiPolicy" \
23 | --approve \
24 | --region {{ eksexample_region }} \
25 | --override-existing-serviceaccounts
26 |
27 | - name: add the EBS CSI Driver helm repo
28 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
29 | kubernetes.core.helm_repository:
30 | name: aws-ebs-csi-driver
31 | repo_url: "https://kubernetes-sigs.github.io/aws-ebs-csi-driver"
32 |
33 | - name: Deploy latest version of EBS CSI Driver chart inside kube-system namespace
34 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
35 | kubernetes.core.helm:
36 | name: aws-ebs-csi-driver
37 | chart_ref: aws-ebs-csi-driver/aws-ebs-csi-driver
38 | release_namespace: kube-system
39 | values:
40 | controller:
41 | serviceAccount:
42 | create: false
43 | name: ebs-csi-controller-sa
44 |
45 | - name: create provisioned iops Storage Class
46 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
47 | kubernetes.core.k8s:
48 | state: present
49 | apply: yes
50 | definition:
51 | kind: StorageClass
52 | apiVersion: storage.k8s.io/v1
53 | metadata:
54 | name: ebs-io1
55 | provisioner: ebs.csi.aws.com
56 | volumeBindingMode: WaitForFirstConsumer
57 | parameters:
58 | csi.storage.k8s.io/fstype: ext4
59 | type: io1
60 | iopsPerGB: "50"
61 | encrypted: "true"
62 |
63 | - name: create additional Storage Classes
64 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
65 | kubernetes.core.k8s:
66 | state: present
67 | apply: yes
68 | definition:
69 | kind: StorageClass
70 | apiVersion: storage.k8s.io/v1
71 | metadata:
72 | name: "ebs-{{ item.name }}"
73 | provisioner: ebs.csi.aws.com
74 | volumeBindingMode: WaitForFirstConsumer
75 | parameters:
76 | csi.storage.k8s.io/fstype: ext4
77 | type: "{{ item.type }}"
78 | encrypted: "true"
79 | loop:
80 | - { name: gp2, type: gp2 }
81 | - { name: sc1, type: sc1 }
82 | - { name: st1, type: st1 }
83 |
--------------------------------------------------------------------------------
/docs/architecture/EksExampleArchitectureDiagram.drawio:
--------------------------------------------------------------------------------
1 | 7V1Zk+I2EP41PDJl2fL1OFzZrUySqZpUNnmihC3AGWNRtpiB/PpItmywZI5ZzGXYmqpFbVkSUn/dn1oHLaM7W/4So/n0N+LjsKVr/rJl9Fq6DoBmsf+4ZCUkmmZkkkkc+EK2FrwF/+E8o5AuAh8npYyUkJAG87LQI1GEPVqSoTgmn+VsYxKWa52jCVYEbx4KVemPwKdTIbVMuH7wDQeTaV41sNzsyQzlucVXSabIJ58bIqPfMroxITT7NFt2cci7L++Y7L3BlqdFy2Ic0YNeCAe6+26/DP9Z9V/+SAbRL6bTFqPxgcKF+Mavi1EYeLy9i1GEqWg7XeU9MidBRNNeNTvsj9XZ1Vome9LlqSfdlARy2i4LgJriZZQFctouC4BcPJDqB3IDNwRKqlS8JtWvbTSQ/RkdsqBhEOFuoX8aE05i5AdsWLokJDGTRSRivdeZ0lnIUoB9/JwGFL/Nkcd79ZOBh8nGJKICAUDP06LjealMgeb882w54Wh7Qp8JfJrEZDFPq/zOMFD5dJhgbxEHdDVcZ36jMXkvCk4TeWNbuqFDxwGQNyEIww153x0YfYvJP3BMA4aS5zCY8Eop4cUikQrxmPJi2dcLoslLmuoZmvhKVfX4KJliXzRHqCSrAi+36jooEMSMDyYzTOMVy5K/kINO2B0divTnBogNIZtu4jcXImE4JkXZa2ixDwJdX0CariDtr9fuA123j66PuXcwhkRTa4LP83PH7jgngI9TRg9wTQU9hYfeRE/h62pHj7PPTyUt3UIz3o3RKJkX3fCA1i1D6/4cF5SgV0BxA3rQPKvjMh+Oq5noaqDjglCCj6bCx6zifZZ9KvgABT7PP96YoBuShf+A0e3DiH0cenwwhyiklYAy9AFXmBMCqqiidkBJTNCqmEdpsAJQjnYyf6QpqMH+BOdjSWI6JRMSobC/lnbYSEV+0THrPC+Ed3iqNP9iSldCQ9CCkrJKJRTF9JlHlJjAC1GSBF4uHgRhni1rGm/P7g5nzSeL2MM7vqcjYjOshgmmOzLqsHoIYxwiGnyUW1I1HOmr7Luh1UYGYYnWJb9ywVozbKusGgY0paHNSlwPdNG0I8ZetabFPODPGI3H/FOFcrygEQ7LA5pjzGMDg+MKKM4C3890ByfBf2hUWIqyje7tApoIS4qXW8X8qKQP25V8Kyy1J8Mt9X4eXvjamK8HNc9CxuNEBP0GNQ8dvA/YmuahsNUvAVtol2FrQXdztPfmN2zrDDB3VdLEhnbG+oV54WYAfIvRLgCuWRq8MYjnSx9Nh7iAzH6IWxeBuK2ZJcXJPfU2iBumuyv/aSCem5UNiDOWTxFj+zEr8HfiY/b0hUwmjPk2A/IZPLZCvs1mPjrQS0Nx9ZCHqqXu/8qntz9I/M5HUstG8jHNvfVpLvb0YRAxqxp5eMhyUZyOoDrd7TmWBYyTTneLKuoPv4IS/kxdne9CKBYjSuFXF25H5VHTXetOprsg395xct583HBUxPMaRk2t3XNP5qegbpZx0s4r/VlPJcrWy8XKBZzOj9n2A2VlJTAuiTJbXe9tGsoyjdsV4dEdaQJoXDsbBKpx7KAkGzPtG0nU3WSVzGdbcFtmROzZwHb6Gtx41gtiVlCQspiIQ1JdDO5pZhfYVdRlnP6TeUWuNqmKvZIkEMWPCGUquZfVFOq3oZr7WBpK5ll3jIMlb0c1bWNqm+I9I21ci6voGyNu9ZAjAK2ydbYshRzZFdwol9W/tHaRkGKd1lg/0BqDLSNzHmsM1C0Ab2/fmmGGwe44HCc70HGv3fBa5p3Ql0MBc1n6khvG8qJ/+/n1ezNAk6nbLtAAw5UWqKwj2Yso2yr7oLzUM3AbXRnTP+Y4RpSRh1pZjQiVSKSlyF4mLSLz1fGVVAtx3P/IokSZuajiMIskresE9ASooZvzspN7mVJat0Fi1Cnl+2LEtJa/yYtm3fGepMkmmGiwe3rJTLTm2nIQ5+ppzgNSNS8wHkdzVEg1a8FuX4jGtG5tvQ6ozLRe9vKIyRwUk3lP6iE9TpnzmGbF/ky3cr3qVLQnV6hTapgLzd5A/5qGmc+G1jHvRsOY16N4aBr1qJkhnac0DPuy5FqHDy27Ai1jfi5hzRuGBPnDEQpRxFfu69E5S5rqG9qFw836nWxv050D2efRG8+PG44dZ0K/c1hU3V7wiMwcHJkJRB/yYy01rSDJkK7YXXNWRMM72Vtz8IbVbHpw7IZVJWhrwvKOVANIh4OybyDeWg/qV3e+yvWY2u6dr8VJ2p/ML22eP81OWagS6t9QhCZ4VmHfbnKeDfcddrGdXIOvd2ZtqoukeMktKArbfpScwxNtmUTfvCfy8o3hQ1CPHzI1aRUpn07scUSmtl3hjtvvBBT9aKQjMg8NbF6WWtqqyW3c9rPdCOH7HgC4uTOGanQThaM2m5KyLk7a3I7EJAz5uYSHNb4aa2wBiVVd3Brfy1FV+0BrbB+7m+an2LwtnUtz97Bz+RyblP9E59hU2tc4V7HvqCrIrypYlSq8Yj9hK4PmhYuE9X2b4zLh938+fMQ1+QhbvzYfcSfBYPPQYLBdS+joqz7CkSKKrnwJrnzASLo3Q8p/Gh+R3+G26SPm85CBVRyNoHF64rEh7mL3MWfmLmzDuXoPoS4uLNtMMdo+wrMKx/7wDZfzDY5uX5dvsNTwQb0KwzfZGBA6X1yc7nSBYVqKRjV1cTq9lO0TUW9aj57JmyBgxWabsy5fWert7Q89u5CejUks5nwn0TU9X+2+lK45F4lQs96KV3+L99PEPzzBL9cQ6d5y82lv1cpvBj43UbYPva4PbuFH5wltO6pv4j930Rj26eyNa+uuI8W14XFsNC/aeCqvPoM8fYbrC87hCR7bevd5Am7AhkkGp5q2zMiOwHb1yzoC+ww7yGHPZg+/pmrsH+y4d6NqyzRKUYeGFXdkCw1zKu7MPi/VsC5BNa74gl/noovhjupb0Gb06hEJuZpIiBwlNw31h1vOGglx1G36Jd3RRsh7x5H/0KIr0iI5nnZCLWLJ9Q/gZWR4/UOCRv9/
--------------------------------------------------------------------------------
/CONTRIBUTING.MD:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4 | documentation, we greatly value feedback and contributions from our community.
5 |
6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7 | information to effectively respond to your bug report or contribution.
8 |
9 |
10 | ## Reporting Bugs/Feature Requests
11 |
12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13 |
14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16 |
17 | * A reproducible test case or series of steps
18 | * The version of our code being used
19 | * Any modifications you've made relevant to the bug
20 | * Anything unusual about your environment or deployment
21 |
22 |
23 | ## Contributing via Pull Requests
24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25 |
26 | 1. You are working against the latest source on the *mainline* branch.
27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29 |
30 | To send us a pull request, please:
31 |
32 | 1. Fork the repository.
33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34 | 3. Ensure local tests pass.
35 | 4. Commit to your fork using clear commit messages.
36 | 5. Send us a pull request, answering any default questions in the pull request interface.
37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38 |
39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41 |
42 |
43 | ## Finding contributions to work on
44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
45 |
46 |
47 | ## Code of Conduct
48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
50 | opensource-codeofconduct@amazon.com with any additional questions or comments.
51 |
52 |
53 | ## Security issue notifications
54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
55 |
56 |
57 | ## Licensing
58 |
59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
60 |
61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
62 |
--------------------------------------------------------------------------------
/tasks/eks-storage-provider-efscsi.task.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: get eks cluster vpc
8 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
9 | shell: >
10 | aws eks describe-cluster --name {{ eksexample_clustername }} \
11 | --query "cluster.resourcesVpcConfig.vpcId" --output text --region {{ eksexample_region }}
12 | register: eks_vpcinfo
13 |
14 | - name: get eks cluster vpc cidr
15 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
16 | shell: >
17 | aws ec2 describe-vpcs --vpc-ids {{ eks_vpcinfo.stdout }} \
18 | --query "Vpcs[].CidrBlock" --output text --region {{ eksexample_region }}
19 | register: eks_vpccidr
20 |
21 | - name: get eks private subnet ids
22 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
23 | shell: >
24 | aws ec2 describe-subnets --region {{ eksexample_region }} --filter Name=vpc-id,Values={{ eks_vpcinfo.stdout }} \
25 | | jq -r '.Subnets[] | select(.Tags[].Value | contains("SubnetPrivate")) | .SubnetId' | sort -u
26 | register: eks_subnetinfo
27 |
28 | - name: create Roles and Policies for efs csi
29 | cloudformation:
30 | profile: "{{ eksexample_aws_profilename }}"
31 | stack_name: "{{ eksexample_clustername }}-storage-provider-efscsi-policy"
32 | state: present
33 | region: "{{ eksexample_region }}"
34 | template: "./cloudformation/eks-storage-provider-efscsi-iam.template.yaml"
35 |
36 | - name: create efs storage for efs csi
37 | cloudformation:
38 | profile: "{{ eksexample_aws_profilename }}"
39 | stack_name: "{{ eksexample_clustername }}-storage-provider-efscsi-storage"
40 | state: present
41 | region: "{{ eksexample_region }}"
42 | template: "./cloudformation/eks-storage-provider-efscsi-storage.template.yaml"
43 | template_parameters:
44 | Ekscidrblock: "{{ eks_vpccidr.stdout }}"
45 | Ekssubnetids: "{{ eks_subnetinfo.stdout | replace('\n', ', ') }}"
46 | Eksvpcid: "{{ eks_vpcinfo.stdout }}"
47 | register: efs_filesystem
48 |
49 | - name: setup service account for efs csi controller
50 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
51 | shell: >
52 | . /home/ec2-user/.bashrc && \
53 | eksctl create iamserviceaccount \
54 | --name efs-csi-controller-sa \
55 | --namespace kube-system \
56 | --cluster "{{ eksexample_clustername }}" \
57 | --attach-policy-arn "arn:aws:iam::{{ caller_info.account }}:policy/EKSStorageProviderEFSCsiPolicy" \
58 | --approve \
59 | --region {{ eksexample_region }} \
60 | --override-existing-serviceaccounts
61 |
62 | - name: add the EFS CSI Driver helm repo
63 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
64 | kubernetes.core.helm_repository:
65 | name: aws-efs-csi-driver
66 | repo_url: "https://kubernetes-sigs.github.io/aws-efs-csi-driver/"
67 |
68 | - name: Deploy latest version of AWS EFS CSI Driver chart inside kube-system namespace
69 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
70 | kubernetes.core.helm:
71 | name: aws-efs-csi-driver
72 | chart_ref: aws-efs-csi-driver/aws-efs-csi-driver
73 | release_namespace: kube-system
74 | values:
75 | controller:
76 | serviceAccount:
77 | create: false
78 | name: efs-csi-controller-sa
79 |
80 | - name: create efs Storage Class
81 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
82 | kubernetes.core.k8s:
83 | state: present
84 | apply: yes
85 | definition:
86 | kind: StorageClass
87 | apiVersion: storage.k8s.io/v1
88 | metadata:
89 | name: efs-sc
90 | provisioner: efs.csi.aws.com
--------------------------------------------------------------------------------
/cloudformation/eks-bastion.template.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | AWSTemplateFormatVersion: '2010-09-09'
8 | Description: Bastion using public subnet
9 | Parameters:
10 | EKSLatestAmazonLinuxAmiId:
11 | Description: AMI id that should be used for the EC2 instaces
12 | Type: 'AWS::SSM::Parameter::Value'
13 | Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
14 | EKSBastionInstanceType:
15 | Description: InstanceType and Size for Bastion Host
16 | Type: String
17 | EKSBastionKeyPairName:
18 | Description: Keypair Name for SSH login
19 | Type: String
20 |
21 | Resources:
22 | EKSBastionRole:
23 | Type: AWS::IAM::Role
24 | Properties:
25 | AssumeRolePolicyDocument:
26 | Version: '2012-10-17'
27 | Statement:
28 | - Effect: Allow
29 | Principal:
30 | Service:
31 | - ec2.amazonaws.com
32 | Action:
33 | - sts:AssumeRole
34 | Policies:
35 | - PolicyName: EKSExample-service
36 | PolicyDocument:
37 | Version: '2012-10-17'
38 | Statement:
39 | - Effect: Allow
40 | Action:
41 | - cloudformation:*
42 | - eks:*
43 | - elasticfilesystem:*
44 | Resource: "*"
45 | ManagedPolicyArns:
46 | - arn:aws:iam::aws:policy/AmazonEC2FullAccess
47 | - arn:aws:iam::aws:policy/AmazonRoute53FullAccess
48 | - arn:aws:iam::aws:policy/IAMFullAccess
49 | - arn:aws:iam::aws:policy/AmazonVPCFullAccess
50 | - arn:aws:iam::aws:policy/AWSCloudFormationReadOnlyAccess
51 | - arn:aws:iam::aws:policy/AWSCertificateManagerFullAccess
52 | Path: "/"
53 |
54 | EKSBastionInstanceProfile:
55 | Type: AWS::IAM::InstanceProfile
56 | Properties:
57 | Path: "/"
58 | Roles:
59 | - Ref: EKSBastionRole
60 |
61 | EKSBastionInstanceSecurityGroup:
62 | Type: AWS::EC2::SecurityGroup
63 | Properties:
64 | GroupDescription: EKS Bastion ECS Instance Security Group
65 |
66 | EKSBastionInstanceSecurityGroupPorts:
67 | Type: AWS::EC2::SecurityGroupIngress
68 | Properties:
69 | GroupId:
70 | Fn::GetAtt:
71 | - EKSBastionInstanceSecurityGroup
72 | - GroupId
73 | IpProtocol: tcp
74 | FromPort: 22
75 | ToPort: 22
76 | CidrIp: 0.0.0.0/0
77 |
78 | EKSBastionInstance:
79 | Type: AWS::EC2::Instance
80 | Properties:
81 | ImageId: !Ref EKSLatestAmazonLinuxAmiId
82 | IamInstanceProfile: !Ref EKSBastionInstanceProfile
83 | InstanceType: !Ref EKSBastionInstanceType
84 | KeyName: !Ref EKSBastionKeyPairName
85 | SecurityGroups:
86 | - !Ref EKSBastionInstanceSecurityGroup
87 | UserData:
88 | Fn::Base64: !Sub |
89 | #!/bin/bash -xe
90 |
91 | yum update -y
92 | yum -y remove aws-cli
93 | yum -y install sqlite telnet jq strace tree gcc glibc-static gettext bash-completion
94 |
95 | pip3 install -U awscli ansible botocore boto boto3 openshift pyyaml
96 | update-alternatives --install /usr/bin/python python /usr/bin/python3 1
97 |
98 | # install helm on bastion
99 | curl -sSL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
100 |
101 | # install ansible kubernetes community collection
102 | /usr/local/bin/ansible-galaxy collection install kubernetes.core
103 |
104 | cd /tmp
105 |
106 | # eksctl install
107 | curl -sSL "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
108 | chmod +x ./eksctl
109 | mv ./eksctl /usr/bin/eksctl
110 |
111 | # kubectl install
112 | curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
113 | chmod +x ./kubectl
114 | mv ./kubectl /usr/bin/kubectl
115 |
116 | Outputs:
117 | EKSBastionInstanceDNSName:
118 | Description: The Bastion Host Public DNS Name
119 | Value:
120 | Fn::GetAtt:
121 | - EKSBastionInstance
122 | - PublicDnsName
123 | EKSBastionInstancePublicIP:
124 | Description: The Bastion Host Public DNS Name
125 | Value:
126 | Fn::GetAtt:
127 | - EKSBastionInstance
128 | - PublicIp
--------------------------------------------------------------------------------
/eks-destroy-cluster.playbook.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2020 ##
5 | #############################################################
6 |
7 | - name: example Kubernetes Workshop Workshop Destruction
8 | hosts: localhost
9 | gather_facts: no
10 |
11 | vars:
12 | ansible_ssh_private_key_file: "./secrets/id_rsa_eks"
13 | ansible_user: ec2-user
14 |
15 | vars_prompt:
16 | - name: "security_check"
17 | prompt: "Do really want to DESTROY your Amazon EKS cluster deployment (yes/no)?"
18 | private: no
19 |
20 | tasks:
21 | - name: check if we're gonna destroy
22 | when: not security_check | bool
23 | fail:
24 | msg: cancelled
25 |
26 | - name: check ansible version
27 | when: (ansible_version.major == 2 and ansible_version.minor < 10 ) or (ansible_version.major < 2)
28 | run_once: yes
29 | fail:
30 | msg: Please use Ansible 2.10 or newer
31 |
32 | - name: import static var data
33 | include_vars:
34 | dir: vars/static
35 | ignore_unknown_extensions: True
36 | extensions:
37 | - yaml
38 |
39 | - name: import dynamic var data
40 | include_vars:
41 | dir: vars/dynamic
42 | ignore_unknown_extensions: True
43 | extensions:
44 | - yaml
45 |
46 | - name: check if eks cluster setup
47 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
48 | shell: eksctl get cluster --region {{ eksexample_region }} --verbose 0
49 | register: eks_check_output
50 |
51 | - name: remove iamserviceaccounts via eksctl
52 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
53 | shell: >
54 | eksctl delete iamserviceaccount \
55 | --name {{ item.name }} \
56 | --namespace {{ item.namespace }} \
57 | --cluster "{{ eksexample_clustername }}" \
58 | --wait \
59 | --region {{ eksexample_region }}
60 | loop:
61 | - { name: cluster-autoscaler, namespace: kube-system }
62 | - { name: external-dns, namespace: kube-system }
63 | - { name: aws-load-balancer-controller, namespace: kube-system }
64 | - { name: ebs-csi-controller-sa, namespace: kube-system }
65 | - { name: efs-csi-controller-sa, namespace: kube-system }
66 | - { name: xray-daemon, namespace: kube-system }
67 | when: not eks_check_output.stdout == "No clusters found"
68 |
69 | - name: destroy cloudformation stacks
70 | cloudformation:
71 | region: "{{ eksexample_region }}"
72 | profile: "{{ eksexample_aws_profilename }}"
73 | stack_name: "{{ item }}"
74 | state: "absent"
75 | loop:
76 | - "{{ eksexample_clustername }}-cluster-autoscaler-policy"
77 | - "{{ eksexample_clustername }}-container-insights-policy"
78 | - "{{ eksexample_clustername }}-external-dns-policy"
79 | - "{{ eksexample_clustername }}-cluster-loadbalancercontroller-policy"
80 | - "{{ eksexample_clustername }}-storage-provider-ebscsi-policy"
81 | - "{{ eksexample_clustername }}-storage-provider-efscsi-policy"
82 | - "{{ eksexample_clustername }}-storage-provider-efscsi-storage"
83 |
84 | - name: check if cert exists on ACM
85 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
86 | shell: >
87 | aws acm list-certificates --region {{ eksexample_region }} \
88 | | jq -r ".CertificateSummaryList | .[] | select (.DomainName == \"{{ eksexample_hostedzonename }}\").CertificateArn"
89 | register: cert_existing
90 |
91 | - name: read ssl cert name
92 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
93 | shell: >
94 | aws acm describe-certificate --certificate-arn "{{ cert_existing.stdout }}" \
95 | --query Certificate.DomainValidationOptions --region {{ eksexample_region }} | jq -r ".[] | select(.DomainName == \"{{ eksexample_hostedzonename }}\").ResourceRecord.Name"
96 | register: ssl_cert_name
97 | when: cert_existing.stdout
98 |
99 | - name: remove ACM Certfificate
100 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
101 | shell: >
102 | aws acm delete-certificate --region {{ eksexample_region }} --certificate-arn "{{ cert_existing.stdout }}"
103 | when: cert_existing.stdout
104 |
105 | - name : delete record set in route53
106 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
107 | route53:
108 | state: absent
109 | zone: "{{ eksexample_hostedzonename }}"
110 | record: "{{ ssl_cert_name.stdout }}"
111 | when: cert_existing.stdout == eksexample_hostedzonename
112 |
113 | - name: destroy amazon eks cluster
114 | delegate_to: "{{ EKSBastionInstancePublicIP }}"
115 | shell: >
116 | eksctl delete cluster \
117 | --name {{ eksexample_clustername }} \
118 | --region {{ eksexample_region }} \
119 | --wait
120 | when: not eks_check_output.stdout == "No clusters found"
121 |
122 | - name: remove bastion host stack
123 | cloudformation:
124 | region: "{{ eksexample_region }}"
125 | profile: "{{ eksexample_aws_profilename }}"
126 | stack_name: "{{ eksexample_clustername }}-bastion"
127 | state: "absent"
128 |
129 | - name: remove ec2 secret key
130 | ec2_key:
131 | state: absent
132 | profile: "{{ eksexample_aws_profilename }}"
133 | name: "{{ eksexample_clustername }}-keypair"
134 | region: "{{ eksexample_region }}"
135 |
136 | - name: find dynamic var files
137 | find:
138 | paths: ./vars/dynamic/
139 | patterns: "*"
140 | register: files_to_delete
141 |
142 | - name: remove dynamic var files
143 | file:
144 | path: "{{ item.path }}"
145 | state: absent
146 | with_items: "{{ files_to_delete.files }}"
147 |
148 | - name: delete local secret file
149 | file:
150 | path: ./secrets/id_rsa_eks
151 | state: absent
152 |
--------------------------------------------------------------------------------
/cloudformation/eks-loadbalancer-controller-iam-policy.template.yaml:
--------------------------------------------------------------------------------
1 | #############################################################
2 | ## NOT FOR PRODUCTION USE. ##
3 | ## THE CONTENT OF THIS FILE IS FOR LEARNING PURPOSES ONLY ##
4 | ## created by David Surey, Amazon Web Services, 2021 ##
5 | #############################################################
6 |
7 | AWSTemplateFormatVersion: "2010-09-09"
8 | Resources:
9 |
10 | EKSloadbalancerControllerPolicy:
11 | Type: 'AWS::IAM::ManagedPolicy'
12 | Properties:
13 | ManagedPolicyName: EKSloadbalancerControllerPolicy
14 | PolicyDocument:
15 | Version: '2012-10-17'
16 | Statement:
17 | - Effect: Allow
18 | Action:
19 | - iam:CreateServiceLinkedRole
20 | Resource: "*"
21 | Condition:
22 | StringEquals:
23 | iam:AWSServiceName: elasticloadbalancing.amazonaws.com
24 | - Effect: Allow
25 | Action:
26 | - ec2:DescribeAccountAttributes
27 | - ec2:DescribeAddresses
28 | - ec2:DescribeAvailabilityZones
29 | - ec2:DescribeInternetGateways
30 | - ec2:DescribeVpcs
31 | - ec2:DescribeVpcPeeringConnections
32 | - ec2:DescribeSubnets
33 | - ec2:DescribeSecurityGroups
34 | - ec2:DescribeInstances
35 | - ec2:DescribeNetworkInterfaces
36 | - ec2:DescribeTags
37 | - ec2:GetCoipPoolUsage
38 | - ec2:DescribeCoipPools
39 | - elasticloadbalancing:DescribeLoadBalancers
40 | - elasticloadbalancing:DescribeLoadBalancerAttributes
41 | - elasticloadbalancing:DescribeListeners
42 | - elasticloadbalancing:DescribeListenerCertificates
43 | - elasticloadbalancing:DescribeSSLPolicies
44 | - elasticloadbalancing:DescribeRules
45 | - elasticloadbalancing:DescribeTargetGroups
46 | - elasticloadbalancing:DescribeTargetGroupAttributes
47 | - elasticloadbalancing:DescribeTargetHealth
48 | - elasticloadbalancing:DescribeTags
49 | Resource: "*"
50 | - Effect: Allow
51 | Action:
52 | - cognito-idp:DescribeUserPoolClient
53 | - acm:ListCertificates
54 | - acm:DescribeCertificate
55 | - iam:ListServerCertificates
56 | - iam:GetServerCertificate
57 | - waf-regional:GetWebACL
58 | - waf-regional:GetWebACLForResource
59 | - waf-regional:AssociateWebACL
60 | - waf-regional:DisassociateWebACL
61 | - wafv2:GetWebACL
62 | - wafv2:GetWebACLForResource
63 | - wafv2:AssociateWebACL
64 | - wafv2:DisassociateWebACL
65 | - shield:GetSubscriptionState
66 | - shield:DescribeProtection
67 | - shield:CreateProtection
68 | - shield:DeleteProtection
69 | Resource: "*"
70 | - Effect: Allow
71 | Action:
72 | - ec2:AuthorizeSecurityGroupIngress
73 | - ec2:RevokeSecurityGroupIngress
74 | Resource: "*"
75 | - Effect: Allow
76 | Action:
77 | - ec2:CreateSecurityGroup
78 | Resource: "*"
79 | - Effect: Allow
80 | Action:
81 | - ec2:CreateTags
82 | Resource: arn:aws:ec2:*:*:security-group/*
83 | Condition:
84 | StringEquals:
85 | ec2:CreateAction: CreateSecurityGroup
86 | 'Null':
87 | aws:RequestTag/elbv2.k8s.aws/cluster: 'false'
88 | - Effect: Allow
89 | Action:
90 | - ec2:CreateTags
91 | - ec2:DeleteTags
92 | Resource: arn:aws:ec2:*:*:security-group/*
93 | Condition:
94 | 'Null':
95 | aws:RequestTag/elbv2.k8s.aws/cluster: 'true'
96 | aws:ResourceTag/elbv2.k8s.aws/cluster: 'false'
97 | - Effect: Allow
98 | Action:
99 | - ec2:AuthorizeSecurityGroupIngress
100 | - ec2:RevokeSecurityGroupIngress
101 | - ec2:DeleteSecurityGroup
102 | Resource: "*"
103 | Condition:
104 | 'Null':
105 | aws:ResourceTag/elbv2.k8s.aws/cluster: 'false'
106 | - Effect: Allow
107 | Action:
108 | - elasticloadbalancing:CreateLoadBalancer
109 | - elasticloadbalancing:CreateTargetGroup
110 | Resource: "*"
111 | Condition:
112 | 'Null':
113 | aws:RequestTag/elbv2.k8s.aws/cluster: 'false'
114 | - Effect: Allow
115 | Action:
116 | - elasticloadbalancing:CreateListener
117 | - elasticloadbalancing:DeleteListener
118 | - elasticloadbalancing:CreateRule
119 | - elasticloadbalancing:DeleteRule
120 | Resource: "*"
121 | - Effect: Allow
122 | Action:
123 | - elasticloadbalancing:AddTags
124 | - elasticloadbalancing:RemoveTags
125 | Resource:
126 | - arn:aws:elasticloadbalancing:*:*:targetgroup/*/*
127 | - arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*
128 | - arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*
129 | Condition:
130 | 'Null':
131 | aws:RequestTag/elbv2.k8s.aws/cluster: 'true'
132 | aws:ResourceTag/elbv2.k8s.aws/cluster: 'false'
133 | - Effect: Allow
134 | Action:
135 | - elasticloadbalancing:AddTags
136 | - elasticloadbalancing:RemoveTags
137 | Resource:
138 | - arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*
139 | - arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*
140 | - arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*
141 | - arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*
142 | - Effect: Allow
143 | Action:
144 | - elasticloadbalancing:ModifyLoadBalancerAttributes
145 | - elasticloadbalancing:SetIpAddressType
146 | - elasticloadbalancing:SetSecurityGroups
147 | - elasticloadbalancing:SetSubnets
148 | - elasticloadbalancing:DeleteLoadBalancer
149 | - elasticloadbalancing:ModifyTargetGroup
150 | - elasticloadbalancing:ModifyTargetGroupAttributes
151 | - elasticloadbalancing:DeleteTargetGroup
152 | Resource: "*"
153 | Condition:
154 | 'Null':
155 | aws:ResourceTag/elbv2.k8s.aws/cluster: 'false'
156 | - Effect: Allow
157 | Action:
158 | - elasticloadbalancing:RegisterTargets
159 | - elasticloadbalancing:DeregisterTargets
160 | Resource: arn:aws:elasticloadbalancing:*:*:targetgroup/*/*
161 | - Effect: Allow
162 | Action:
163 | - elasticloadbalancing:SetWebAcl
164 | - elasticloadbalancing:ModifyListener
165 | - elasticloadbalancing:AddListenerCertificates
166 | - elasticloadbalancing:RemoveListenerCertificates
167 | - elasticloadbalancing:ModifyRule
168 | Resource: "*"
169 |
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | ***Status:** Work-in-progress. Please create issues or pull requests if you have ideas for improvement.*
2 |
3 | # **Amazon EKS full automated deployment with Ansible**
4 | Example deployment of Amazon EKS using Ansible and Cloudformation.
5 |
6 | ## Summary
7 | This project demonstrates the deployment of an Amazon EKS cluster and basic services using Ansible and Amazon Cloudformation. The deployment is fully automated and will enable you to start learing and testing the elasticity and agility of AWS Services used with Kubernetes based microservice architectures.
8 |
9 | ## High-Level Architecture
10 |
11 | 
12 |
13 | ## Disclaimer
14 | This project is an example of an deployment and meant to be used for testing and learning purposes only. Do not use in production.
15 |
16 | **Be aware that the deployment is not covered by the AWS free tier. Please use the [AWS pricing calculator](https://calculator.aws/#/estimate) to an estimation beforehand**
17 |
18 | # Table of Contents
19 |
20 | 1. [Getting started](#Getting-started)
21 | 2. [Prerequisites](#Prerequisites)
22 | 3. [Parameters](#Parameters)
23 | 4. [Templates](#Templates)
24 | 5. [Testing](#Testing)
25 | 6. [Resources](#Resources)
26 | 7. [Security](#Security)
27 | 8. [License](#License)
28 |
29 | # Getting started
30 |
31 | Just a few steps are needed to get started with the example deployment.
32 | the deployment process is seperated in a cluster deployment containing the creation of the Amazon EKS cluster itself and various cluster extensions and optional demo/example deployments to show the Amazon EKS cluster and the extensions in action.
33 |
34 | You may use the [deployment playbook](./eks-deploy-cluster.playbook.yaml) for the [automatic deployment](#automatic) of Amazon EKS via Ansible. To destroy/remove the Amazon EKS deployment from your AWS Account you can use the [destroy playbook](./eks-destroy-cluster.playbook.yaml).
35 |
36 | ## Prerequisites
37 |
38 | To run the Ansible based deployment you need to have some software installed and configured on your device:
39 |
40 | - bash (zsh, csh, sh should also work, not tesed though)
41 | - an [installed and configured ](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) aws-cli
42 | - [a named profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) at the aws-cli configuration reflecting the account you are planning to use for the deployment
43 | - [jq](https://stedolan.github.io/jq/)
44 | - a working [Ansible installation](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)
45 | - an install of the community kubernetes [Ansible module](https://github.com/ansible-collections/community.kubernetes)
46 | - some pip modules: botocore boto boto3
47 |
48 | For the DNS Automation to work you'll need to have a [Hosted Zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/AboutHZWorkingWith.html) setup at your AWS Account
49 |
50 | ## Parameters
51 |
52 | **Deployment parameters:**
53 |
54 | Some static deployment variables are to be altered/placed into the [vars/static/definitions.yaml](vars/static/definitions.yaml)
55 |
56 | | Parameter Name | Default Value | Description | Comment |
57 | | ---- | ---- | ---- | ---- |
58 | | eksexample_region | eu-central-1 | the region to be used for deployments | define the region to be used. Please be aware that the Amazon EKS on AWS Fargate used in some examples is not available in all [regions](https://docs.aws.amazon.com/eks/latest/userguide/fargate.html)
59 | | eksexample_worker_desiredcount | 2 | desired worker nodes to start with |
60 | | eksexample_worker_maxcount | 10 | maximum workers to be provisoned if scaling out the cluster |
61 | | eksexample_worker_mincount | 2 | minimum worker nodes | i recommend at least 2 |
62 | | eksexample_worker_instancetype | t3a.medium | instance size of the worker nodes |
63 | | eksexample_bastion_instancetype | t3a.small | instance size of the bastion host |
64 | | eksexample_clustername | ansible-eks-testcluster | name of the Amazon EKS cluster |
65 | | eksexample_clusterversion | 1.18 | version of the Amazon EKS cluster | versions <1.16 are not tested with this automation
66 | | eksexample_aws_profilename | ansible | the [profile name setup](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) for the local awscli | i recommend to setup a local profile. if you decide to shift it directly to instance_profile based EC2 admin instances, alter the ansible module parameters to not use "profile:"
67 |
68 | rename the [vars/static/custom_definitions.yaml](vars/static/custom_definitions.yaml.example) and alter the parameters according to your needs
69 | | Parameter Name | Default Value | Description | Comment |
70 | | ---- | ---- | ---- | ---- |
71 | | eksexample_hostedzoneid | | the ID of your Route53 Zone where the DNS automation should work on. |
72 | | eksexample_hostedzonename | | the Domainname of the Hosted Zone on Route53 |
73 |
74 |
75 | # Deployment
76 |
77 | The deployment will take approx 30-45 minutes.
78 |
79 | # Template structure and deployment workflow
80 |
81 | The Deployment consists of one main playbook triggering multible tasks, cloudformation templates and kubernetes manifests
82 |
83 | ## Playbooks
84 |
85 | - eks-deploy-cluster.playbook.yaml: this playbook starts the overall deployment of the Amazon EKS cluster and triggers also the deployment of all extensions. can be started with ansible-playbook ./eks-deploy-cluster.playbook.yaml
86 | - eks-destroy-cluster.playbook.yaml: this playbook destroys the whole deployment. If you deployed the example deployments into the cluster, make sure these get destroyed first using the ./docs/examples/destroy-examples.playbook.yaml playbook.
87 | - ./docs/examples/deploy-examples.playbook.yaml: this playbook will deploy some microservice and overall deployment examples to demonstrate the functionality of the extensions.
88 | - ./docs/examples/destroy-examples.playbook.yaml: will remove the example deployments from the cluster (but leaves the cluster intact)
89 |
90 | ## Tasks
91 | - acm.tasks.yaml: Sets up ACM and adds the validation Records into the defined Hosted Zone.
92 | - bastion.tasks.yaml: Sets up a Bastion Hosts used for the Amazon EKS deplyoment as well as all Kubernetes Deployments. Using the Bastion we'll not have to expose any ports/services of the Amazon EKS cluster backend to public internet.
93 | - eks-cluster.task.yaml: deploys the Amazon EKS cluster and enables the logging for the masterplane
94 | - eks-cluster-autoscaler.task.yaml: setup of the [cluster-autoscaler](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler)
95 | - eks-container-insights.task.yaml: enable [container insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html) for the Amazon EKS cluster
96 | - eks-external-dns.task.yaml: setup of the Route53 automation via [external-dns](https://github.com/kubernetes-sigs/external-dns)
97 | - eks-ingress-controller.task.yaml: setup of the [aws-load-balancer-controller](https://github.com/kubernetes-sigs/aws-load-balancer-controller) to automate service exposure
98 | - eks-metrics-server.task.yaml: setup of the metrics server used by the [Horizontal Pod Autoscaler](https://kubernetes.io/de/docs/tasks/run-application/horizontal-pod-autoscale/)
99 | - eks-storage-provider-ebscsi.task.yaml: setup of the [Amazon Elastic Block Store (EBS) CSI driver](https://github.com/kubernetes-sigs/aws-ebs-csi-driver). The driver will ensure automatic provisioning of persistent block storage volumes for workloads
100 | - eks-storage-provider-efscsi.task.yaml: setup of the [Amazon EFS CSI driver](https://github.com/kubernetes-sigs/aws-efs-csi-driver). The driver will ensure automatic provisioning of persistent shared storage volumes for workloads
101 | - eks-xray.task.yaml: setup of the [X-Ray deamon setup](https://github.com/aws-samples/aws-xray-kubernetes) to trace application deployments
102 |
103 | ## Cloudformation Templates
104 | - eks-bastion.template.yaml
105 | - eks-cluster-autoscaler-iam.template.yaml: provisioning of the IAM Policy granting access for the cluster autoscaler to Amazon EC2 and EC2 Autoscaling groups.
106 | - eks-container-insights-iam.template.yaml: provisioning of the IAM Policy allowing Amazon Cloudwatch Access via the Worker Nodes
107 | - eks-external-dns-iam.template.yaml: provisioning of the IAM Policy granting access for the external-dns pods to Route53
108 | - eks-ingress-controller-iam.template.yaml: provisioning of the IAM Policy granting access for the aws-load-balancer-controller towards Elastic Load Balancing
109 | - eks-storage-provider-ebscsi-iam.template.yaml: IAM Policies to Allow EBS Access via the CSI Driver Deployment
110 | - eks-storage-provider-efscsi-storage.template.yaml: provisioning of the EFS FileSystem, Mountpoints and related Securitygroups
111 |
112 | ## Kubernetes Manifests
113 |
114 | All Manifests used for the Kubernetes Service and Application deployments are seperated into subfolders of either [./k8s/](./k8s) or [./docs/examples/k8s](./docs/examples/k8s)
115 | These Manifests are triggered using the community.kubernetes modules via the Ansible tasks.
116 |
117 | ## additional Files
118 | - [ansible.cfg](./ansible.cfg): contains some tweaks for the SSH connectivity, logging and so on.
119 | - ansible.log: will be written on each run but not checked into the git repo (-> [.gitignore](.gitignore) )
120 | - [./vars/dynamic/*.yaml](./vars/dynamic): Variable files written by the playbooks. Contain information about SSL Arns and Bastion Host IP/Name Details.
121 | - [./secrets/id_rsa_eks](./secrets/id_rsa_eks): this file contains the private ssh key to log into the bastion host via SSH. this is used by the Ansible playbooks but may be also used by you to log into the bastion to do some testing. this file will not be checked into git (-> [.gitignore](.gitignore) )
122 | ---
123 | # Testing
124 |
125 | When the deployment of the cluster is fullfilled you may test your setup. some useful commands to see what actually got deployed:
126 |
127 | first of all you should log into your bastion host. from there you will find a ready to use kubeconfig within [.kube/config](.kube/config)
128 |
129 | to see if nodes are there and your access to the Amazon EKS cluster is working type:
130 | ```
131 | kubectl get nodes
132 | ```
133 |
134 | should give you something like:
135 | ```
136 | NAME STATUS ROLES AGE VERSION
137 | ip-192-168-43-140.eu-central-1.compute.internal Ready 15m v1.17.9-eks-4c6976
138 | ip-192-168-93-136.eu-central-1.compute.internal Ready 15m v1.17.9-eks-4c697
139 | ```
140 |
141 | to see if the pods of the extensions are up and running you may use:
142 | ```
143 | kubectl get pod -o=wide -n kube-system
144 | ```
145 |
146 | which should show something like:
147 | ```
148 | NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
149 | aws-load-balancer-controller-7568799df8-pnch4 1/1 Running 0 7m30s 192.168.45.158 ip-192-168-43-140.eu-central-1.compute.internal
150 | aws-node-7vg6h 1/1 Running 0 17m 192.168.93.136 ip-192-168-93-136.eu-central-1.compute.internal
151 | aws-node-scl29 1/1 Running 0 17m 192.168.43.140 ip-192-168-43-140.eu-central-1.compute.internal
152 | cluster-autoscaler-7884f5ff6d-k6vpw 1/1 Running 0 8m44s 192.168.68.113 ip-192-168-93-136.eu-central-1.compute.internal
153 | coredns-5fdf64ff8-7m4bd 1/1 Running 0 21m 192.168.70.235 ip-192-168-93-136.eu-central-1.compute.internal
154 | coredns-5fdf64ff8-cnwlc 1/1 Running 0 21m 192.168.52.7 ip-192-168-43-140.eu-central-1.compute.internal
155 | ebs-csi-controller-668bbc964-2ttdt 4/4 Running 0 13m 192.168.88.219 ip-192-168-93-136.eu-central-1.compute.internal
156 | ebs-csi-controller-668bbc964-pt8n4 4/4 Running 0 13m 192.168.41.152 ip-192-168-43-140.eu-central-1.compute.internal
157 | ebs-csi-node-qq5r8 3/3 Running 0 13m 192.168.43.140 ip-192-168-43-140.eu-central-1.compute.internal
158 | ebs-csi-node-zsxs9 3/3 Running 0 13m 192.168.93.136 ip-192-168-93-136.eu-central-1.compute.internal
159 | ebs-snapshot-controller-0 1/1 Running 0 13m 192.168.32.10 ip-192-168-43-140.eu-central-1.compute.internal
160 | efs-csi-node-dzz5j 3/3 Running 0 11m 192.168.93.136 ip-192-168-93-136.eu-central-1.compute.internal
161 | ...
162 | ```
163 |
164 | you can check if for instance the ingress-controller is working as expected using:
165 | ```
166 | kubectl logs -n kube-system $(kubectl get po -n kube-system | egrep -o alb-ingress[a-zA-Z0-9-]+)
167 | ```
168 |
169 | if everything is cool it should look like:
170 | ```
171 | -------------------------------------------------------------------------------
172 | AWS ALB Ingress controller
173 | Release: v1.1.8
174 | Build: git-ec387ad1
175 | Repository: https://github.com/kubernetes-sigs/aws-load-balancer-controller.git
176 | -------------------------------------------------------------------------------
177 |
178 | W0813 14:32:48.050307 1 client_config.go:549] Neither --kubeconfig nor --master was specified. Using the inClusterConfig. This might not work.
179 | I0813 14:32:48.096117 1 controller.go:121] kubebuilder/controller "level"=0 "msg"="Starting EventSource" "controller"="aws-load-balancer-controller" "source"={"Type":{"metadata":{"creationTimestamp":null}}}
180 | I0813 14:32:48.096518 1 controller.go:121] kubebuilder/controller "level"=0 "msg"="Starting EventSource" "controller"="aws-load-balancer-controller" "source"={"Type":{"metadata":{"creationTimestamp":null},"spec":{},"status":{"loadBalancer":{}}}}
181 | I0813 14:32:48.096622 1 controller.go:121] kubebuilder/controller "level"=0 "msg"="Starting EventSource" "controller"="aws-load-balancer-controller" "source"=
182 | I0813 14:32:48.096910 1 controller.go:121] kubebuilder/controller "level"=0 "msg"="Starting EventSource" "controller"="aws-load-balancer-controller" "source"={"Type":{"metadata":{"creationTimestamp":null},"spec":{},"status":{"loadBalancer":{}}}}
183 | I0813 14:32:48.096963 1 controller.go:121] kubebuilder/controller "level"=0 "msg"="Starting EventSource" "controller"="aws-load-balancer-controller" "source"=
184 | I0813 14:32:48.097188 1 controller.go:121] kubebuilder/controller "level"=0 "msg"="Starting EventSource" "controller"="aws-load-balancer-controller" "source"={"Type":{"metadata":{"creationTimestamp":null}}}
185 | I0813 14:32:48.098011 1 controller.go:121] kubebuilder/controller "level"=0 "msg"="Starting EventSource" "controller"="aws-load-balancer-controller" "source"={"Type":{"metadata":{"creationTimestamp":null},"spec":{},"status":{"daemonEndpoints":{"kubeletEndpoint":{"Port":0}},"nodeInfo":{"machineID":"","systemUUID":"","bootID":"","kernelVersion":"","osImage":"","containerRuntimeVersion":"","kubeletVersion":"","kubeProxyVersion":"","operatingSystem":"","architecture":""}}}}
186 | I0813 14:32:48.103658 1 controller.go:121] kubebuilder/controller "level"=0 "msg"="Starting EventSource" "controller"="aws-load-balancer-controller" "source"={"Type":{"metadata":{"creationTimestamp":null},"spec":{"containers":null},"status":{}}}
187 | I0813 14:32:48.105447 1 leaderelection.go:205] attempting to acquire leader lease kube-system/ingress-controller-leader-alb...
188 | I0813 14:32:48.119414 1 leaderelection.go:214] successfully acquired lease kube-system/ingress-controller-leader-alb
189 | I0813 14:32:48.119775 1 recorder.go:53] kubebuilder/manager/events "level"=1 "msg"="Normal" "message"="aws-load-balancer-controller-7568799df8-pnch4_dc09d9d6-dd71-11ea-a82f-6e94ec7ac6f2 became leader" "object"={"kind":"ConfigMap","namespace":"kube-system","name":"ingress-controller-leader-alb","uid":"5e3275ce-3936-411a-9de5-4503c2223c8b","apiVersion":"v1","resourceVersion":"3156"} "reason"="LeaderElection"
190 | I0813 14:32:48.222253 1 controller.go:134] kubebuilder/controller "level"=0 "msg"="Starting Controller" "controller"="aws-load-balancer-controller"
191 | I0813 14:32:48.322547 1 controller.go:154] kubebuilder/controller "level"=0 "msg"="Starting workers" "controller"="aws-load-balancer-controller" "worker count"=1
192 | ```
193 | if you replace *alb-ingress* with *external-dns* or *cluster-autoscaler* you can use the same command to get the logs of these extensions as well.
194 |
195 | ## Testing the example deployments
196 |
197 | if you deployed the example(s) via [./docs/examples/deploy-examples.playbook.yaml](./docs/examples/deploy-examples.playbook.yaml) you can check some neat details.
198 |
199 | to check the Horizontal Pod Autscaler coming with the example-microservice use:
200 |
201 | ```
202 | watch -n 1 kubectl get hpa -n eksdemo
203 | ```
204 | which will give you:
205 | ```
206 | NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
207 | eksdemo-crystal Deployment/eksdemo-crystal 1%/30% 2 10 1 17s
208 | eksdemo-frontend Deployment/eksdemo-frontend 3%/30% 2 10 0 14s
209 | eksdemo-nodejs Deployment/eksdemo-nodejs 2%/30% 2 10 1 20s
210 | ```
211 |
212 | then open the test webpage using your browser of choise. the web address will be "https://eksdemo. + what you used for the variable "eksexample_hostedzonename"
213 | open the page on multiple tabs should generate some load you'll recordnize.
214 | you also can use for instance curl as a load generator
215 |
216 | ```
217 | watch -n 0.1 curl -v https://eksdemo.example.com
218 | ```
219 |
220 | There are many other things to try out. Feel free to share your ideas :)
221 |
222 | ---
223 | # Resources
224 |
225 | - AWS Services
226 | - [Amazon Cloudformation](https://aws.amazon.com/cloudformation/)
227 | - [Amazon EKS](https://aws.amazon.com/ec2/)
228 | - [AWS Certificate Manager](https://aws.amazon.com/certificate-manager/)
229 | - [Amazon Cloudwatch](https://aws.amazon.com/cloudwatch/)
230 | - [Amazon Route53](https://aws.amazon.com/route53/)
231 | - [Elastic Load Balancing](https://aws.amazon.com/elasticloadbalancing/)
232 | - [Amazon EC2 Auto Scaling](https://aws.amazon.com/ec2/autoscaling/)
233 | - [Amazon Virtual Private Cloud](https://aws.amazon.com/vpc/)
234 | - [Amazon Elastic File Service](https://aws.amazon.com/efs/)
235 |
236 | - Open Source Projects
237 | - [Ansible](https://github.com/ansible/ansible)
238 | - [Kubectl](https://kubernetes.io/docs/reference/kubectl/kubectl/)
239 | - [eksctl](https://github.com/weaveworks/eksctl)
240 | - [cluster-autoscaler](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler)
241 | - [external-dns](https://github.com/kubernetes-sigs/external-dns)
242 | - [aws-load-balancer-controller](https://github.com/kubernetes-sigs/aws-load-balancer-controller)
243 | - [Horizontal Pod Autoscaler](https://kubernetes.io/de/docs/tasks/run-application/horizontal-pod-autoscale/)
244 | - [Amazon EFS CSI driver](https://github.com/kubernetes-sigs/aws-efs-csi-driver)
245 | - [Amazon Elastic Block Store (EBS) CSI driver](https://github.com/kubernetes-sigs/aws-ebs-csi-driver)
246 |
247 | # Security
248 |
249 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
250 |
251 | # License
252 |
253 | This Example is licensed under the MIT-0 License. See the LICENSE file.
254 |
255 | Individual files may contain code by other authors under other
256 | licenses. See their license headers for details.
--------------------------------------------------------------------------------