K8s Cluster on AWS Using Ansible
This project consists of using only Ansible to create a Kubernetes cluster on AWS and utilize essential resources to know for those who work directly with Ansible. Although Terraform in my opinion is the best tool for cloud provisioning, we can also do this via Ansible. Of course, we could combine the best of both tools along with Packer, but we'll stick with Ansible only to gain more knowledge.
For this project, we'll learn how to create a good directory structure for your playbooks and how to separate files in order to make it very practical to manage and maintain. For this, Ansible provides a command called ansible-galaxy that helps create a very good directory structure. Additionally, ansible-galaxy is used to install module collections developed by the community.
Requirementsβ
-
An account on AWS
-
Ansible installed. See the installation tutorial if necessary.
Project Phasesβ
- 1 Provisioning => In this phase we need to build the infrastructure on AWS
- 2 Setup => We need to install and configure the cluster
- 3 Deploy => We'll deploy an example application on the cluster
- 4 Monitoring => We'll install Prometheus and Grafana to monitor our cluster
Directory Structureβ
Inside the ./src/ folder is where the project will actually happen.
This directory will contain the phase directories.
Inside each phase we'll have the following files.
- the hosts, our inventory for each phase
- The ansible.cfg file to have our Ansible configurations for each phase
- The roles directory that will actually have our playbooks
- A README.md explaining each phase of the project
~/projects/ansible/study-ansible/Projeto K8S Cluster main !5 ?2 1.1.7 11:51:00
β― touch ansible.cfg hosts main.yml
We're going to create a folder called roles that will contain our playbooks, our tasks. For this, we'll use the binary called ansible-galaxy. Along with Ansible come several binaries that help us besides galaxy, worth checking out.

Let's set up the directories referring to the phases.
~/projects/ansible/study-ansible/Projeto K8S Cluster main !5 ?2 1.1.7 11:41:43
β― cd roles
~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:41:48
β― ansible-galaxy init provisioning
- Role provisioning was created successfully
~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:41:59
β― ansible-galaxy init setup
- Role setup was created successfully
~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:42:05
β― ansible-galaxy init deploy_app
- Role deploy_app was created successfully
~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:42:21
β― ansible-galaxy init deploy_monitoring
- Role deploy_monitoring was created successfully
~/projects/ansible/study-ansible/Projeto K8S Cluster/roles main !5 ?2 1.1.7 11:42:28
Inside each of our tasks can exist sub-tasks, or even sub-sub-tasks. So it will be necessary to create a roles folder inside each of our initial roles, but we'll do this along the way as needed.
~/projects/ansible/study-ansible/Projeto K8S Cluster main !5 ?2 1.1.7 11:51:11
β― tree
.
βββ ansible.cfg
βββ hosts
βββ main.yml
βββ pics
β βββ binarios ansibles.jpg
βββ README.md
βββ roles
βββ deploy_app
β βββ defaults
β β βββ main.yml
β βββ files
β βββ handlers
β β βββ main.yml
β βββ meta
β β βββ main.yml
β βββ README.md
β βββ tasks
β β βββ main.yml
β βββ templates
β βββ tests
β β βββ inventory
β β βββ test.yml
β βββ vars
β βββ main.yml
βββ deploy_monitoring
β βββ defaults
β β βββ main.yml
β βββ files
β βββ handlers
β β βββ main.yml
β βββ meta
β β βββ main.yml
β βββ README.md
β βββ tasks
β β βββ main.yml
β βββ templates
β βββ tests
β β βββ inventory
β β βββ test.yml
β βββ vars
β βββ main.yml
βββ provisioning
β βββ defaults
β β βββ main.yml
β βββ files
β βββ handlers
β β βββ main.yml
β βββ meta
β β βββ main.yml
β βββ README.md
β βββ tasks
β β βββ main.yml
β βββ templates
β βββ tests
β β βββ inventory
β β βββ test.yml
β βββ vars
β βββ main.yml
βββ setup
βββ defaults
β βββ main.yml
βββ files
βββ handlers
β βββ main.yml
βββ meta
β βββ main.yml
βββ README.md
βββ tasks
β βββ main.yml
βββ templates
βββ tests
β βββ inventory
β βββ test.yml
βββ vars
βββ main.yml
38 directories, 37 files
Hosts - Detailsβ
About hosts it's worth learning some things https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html
If you see the documentation you'll notice that it's possible to pass variables to all hosts or specific hosts.
Define what the Python interpreter path is, this prevents it from searching around and if it's not in the path giving some kind of error for this we define ansible_python_interpreter
let's start with a hosts like this:
# global variables
[all:vars]
ansible_python_interpreter=/usr/bin/python
ntp_server=br.pool.ntp.org
[local]
localhost
# local group variables
[local:vars]
ansible_connection=local
gather_facts=false
# will be filled later automatically
[kubernetes]
Main.yml - Detailsβ
This will only serve to make includes (call another file) of our phases according to what we're doing, so it will be filled according to our development, but let's leave the first call as an example.
---
# Only includes here of the tasks
- include: provisioning
Learning During the Projectβ
The use of tags is interesting because you can execute only a specific playbook, or even deny some.
will only execute tagA and tagB
ansible-playbook -i hosts main.yml --tags "tagA,tagB"
won't execute tagA and tagB
ansible-playbook -i hosts main.yml --skip-tags "tagA,tagB"