Ansible
Setup
- git clone diveintoansible github repo (make sure
.envis there) - Now,
docker-compose up - Move to
localhost:1000 - Connect to main
ansiblecontainer - SSH password to all the containers is:
password
How to verify whose remote system fingerprint is in ~/.ssh?
- Go to
~/.ssh cat known_hosts-> list of all the fingerprints ever accepted.ssh-keygen -H -F ubuntu1-> shows the fingerprint for the specified system.
Setup key pairs for authentication
- It's repetitive to enter password everytime we
sshinto the remote server. The better way is to generate key pairs and exchangepublic keywith the remote server.
1) Generate key pair:
inside the admin server. 2) Copy it to child servers: 3) Now, tryssh'ing into the remote servers, you'll login without password.
Automate!
for user in ansible root
do
for os in ubuntu centos
do
for instance in 1 2 3
do
ssh-copy-id -o StrictHostKeyChecking=no ${user}@${os}${instance}
done
done
done
4) Ping the child server with:
Inside Ansible
Repo Setup
git clone https://github.com/spurin/diveintoansible
Check info about ansible and other configurations
Configuration Files
- Define the Ansible behavior.
- The priority of using configuration files by ansible is in the following order:
- 1) ANSIBLE_CONFIG (env variable, with a filename target)
- i.e.
export ANSIBLE_CONFIG=/home/directory/example_ansible.cfg - Can remove the
envvariable using:unset ANSIBLE_CONFIG
- i.e.
- 2)./ansible.cfg (hidden file; in the current directory)
- 3)~/.ansible.cfg (hidden file; in the users home directory)
- 4)/etc/ansible/ansible.cfg
- 1) ANSIBLE_CONFIG (env variable, with a filename target)
Inventory Files
They are plain text files that serve as a central source of information about the managed nodes (hosts). - Hosts - Groups
I) Example
Dir structure:
- ansible.cfg
- known_hosts
ansible.cfg
hosts
Try to do: ansible all -m ping
[!NOTE] To skip fingerprint verification, add following to
ansible.cfg:host_key_checking=False
II) Groups
hosts
Ping with ansible all -m ping or specific one with ansible centos/centos1 -m ping.
[!TIP] Can also use regex for ping i.e.
CONDENSED OUTPUT
ansible all -m ping -o
III) Listing hosts
- ansible centos --list-hosts
- ansible all --list-hosts
- ansible *1 --list-hosts (regex)
IV) Different User & Port
We can include a different user as well as the ansible connection port in our hosts file.
[centos]
centos1 ansible_user=root ansible_port=22
centos2 ansible_user=root
[ubuntu]
ubuntu1 ansible_become=true ansible_become_pass=password
- The port can also be written as:
COMMAND To check about the user in the child servers, do:
ansible all -a 'id' -o
V) Local connection
For the host server, we can also mention it in the hosts.
VI) :vars (removing redundant args)
We can remove repetitive arguments using :vars.
[centos]
centos[1:3]
[centos:vars]
ansible_user=root
[ubuntu]
ubuntu[1:3]
[ubuntu:vars]
ansible_become=true
ansible_become_pass=password
If we want to make a var global but with less precedence than in-line defined var, do:
VII) :children (grouping)
We can also group groups and ping with the group name.
VIII) Corresponding yaml file
---
control:
hosts:
ubuntu-c:
ansible_connection: local
centos:
hosts:
centos1:
ansible_port: 2222
centos2:
centos3:
vars:
ansible_user: root
ubuntu:
hosts:
ubuntu1:
ubuntu2:
ubuntu3:
vars:
ansible_become: true
ansible_become_pass: password
linux:
children:
centos:
ubuntu:
...
[!NOTE] Ansible also supports
json. The specific inventory file can be specified by:ansible all -i hosts.json -o -m ping.
IX) Passing env through cmd
ansible linux -m ping -e 'ansible_port=22' -o
Modules
Used for gathering facts when executing playbooks.
setup module
- for getting info about the remote server
ansible centos1 -m setuporansible centos1 -m setup | more
file module
- sets attributes of files, dirs or symlinks and their targets.
ansible all -m file -a 'path=/placeholder.txt state=touch'
copy module
ansible all -m copy -a 'src=/home/X.txt dest=/home/X.txt'
command module
- takes command name followed by a list of space-delimited arguments.
- the command is not processed through shell, so variables like
$HOMEwill not work.
ansible all -a 'whoami' -o
YAML
Ansible Playbooks
- Contains a list of plays.
---
- # minus indicates a YAML list item. Each list represents a play.
Hosts:
- where our play will run and the options it will run with
Vars:
- variables that will apply to the hosts
Tasks:
- list of tasks to be executed
Handlers:
- handlers to be notified
Roles:
- list of roles to be imported into the play
...
Example 1 (vars)
---
-
hosts: centos
vars:
message: "Oh my my by One Republic."
tasks:
- name: Message
copy:
content: "{{ message }}"
dest: /home/message
...
- Can also pass
envvar using terminal like:ansible-playbook example.yaml -e 'message="hello world"'
Example 2 (handlers)
- handlers are the tasks that run only when notified.
---
-
hosts: centos
vars:
message: "Run by One Republic."
tasks:
- name: Message
copy:
content: "{{ message }}"
dest: /home/message
notify: Message is changed # same name in handlers' name
handlers:
- name: Message is changed
debug:
msg: The message has been changed now, it is now "{{ message }}"
...
[!INFO] For extra information about a remote server, do:
ansible all -i ubuntu1, -m setup | more
Example 3 (conditions)
---
-
hosts: linux
vars:
motd_centos: "Welcome to CentOS Linux - Ansible Rocks\n"
motd_ubuntu: "Welcome to Ubuntu Linux - Ansible Rocks\n"
tasks:
- name: Configure a MOTD (message of the day)
copy:
content: "{{ motd_centos }}"
dest: /etc/motd
notify: MOTD changed
when: ansible_distribution == "CentOS" # the variable is in setup module
- name: Configure a MOTD (message of the day)
copy:
content: "{{ motd_ubuntu }}"
dest: /etc/motd
notify: MOTD changed
when: ansible_distribution == "Ubuntu"
handlers:
- name: MOTD changed
debug:
msg: The MOTD was changed
...
[!NOTE] Variables need not be under
quotesbut under only specific syntax-error prone scenarios.
Example Exercise
- We have two os: CentOS and Ubuntu.
- We create two files:
TEXTandmessage. - Then, we delete those two.
create.yaml
---
-
hosts: linux
vars:
file1: "TEXT"
file2: "message"
centos: "CentOS"
ubuntu: "Ubuntu"
tasks:
- name: Create file on "{{ centos }}"
file:
path: /home/{{ item }}
state: touch
mode: u=rw,g=r,o=r
when: ansible_distribution == centos
with_items:
- "{{ file1 }}"
- "{{ file2 }}"
notify:
- Files created in "{{ centos }}"
- name: Create file in "{{ ubuntu }}"
file:
path: "/home/{{ file1 }}"
state: touch
mode: u=rw,g=r,o=r
when: ansible_distribution == ubuntu
notify:
- File created in "{{ ubuntu }}"
handlers:
- name: Files created in "{{ centos }}"
debug:
msg: "{{ file1 }} and {{ file2 }} created"
- name: File created in "{{ ubuntu }}"
debug:
msg: "{{ file1 }} created"
...
delete.yaml
---
-
hosts: linux
vars:
file1: "TEXT"
file2: "message"
centos: "CentOS"
ubuntu: "Ubuntu"
tasks:
- name: Delete "{{ file1 }}" and "{{ file2 }}" on "{{ centos }}"
file:
path: "/home/{{ item }}"
state: absent
with_items:
- "{{ file1 }}"
- "{{ file2 }}"
when: ansible_distribution == centos
notify: centos file delete
- name: Delete "{{ file1 }}" on "{{ ubuntu }}"
file:
path: "/home/{{ file1 }}"
state: absent
when: ansible_distribution == ubuntu
notify: ubuntu file delete
handlers:
- name: centos file delete
debug:
msg:
- "{{ file1 }} deleted in centos"
- "{{ file2 }} deleted in centos"
- name: ubuntu file delete
debug:
msg: "{{ file1 }} deleted in ubuntu"
...
ansible.cfg
hosts
[control]
ubuntu-c ansible_connection=local
[centos]
centos[1:3]
[centos:vars]
ansible_user=root
[ubuntu]
ubuntu[1:3]
[ubuntu:vars]
ansible_become=true
ansible_become_pass=password
[linux:children]
centos
ubuntu
[!NOTE] We can also specify an external
yamlfile in thevarssection:vars: external_vars.yaml. Then we can reference thosevarsjust by their name insideexternal_vars.yaml.
Example 4 (user input)
---
hosts: centos1
gather_facts: False
vars_prompt:
- name: yourname
private: False # setting to True doesn't show the user input
tasks:
- name: Test vars_prompt
debug:
msg: "{{ yourname }}"
...
Hostvars & Groupvars
Hostvars host_vars/hostname (i.e. host_vars/ubuntu-c) - This stores vars for the hosts: - centos1 - ubuntu1 - ubuntu-c
- This dir has a vars file named corresponding to the host.
centos1
Groupvars group_vars/group (i.e. group_vars/ubuntu) - Similarly, these for the groups. In our case: - centos - ubuntu
Playbook Facts
-
To get a fact using regex:
ansible centos1 -m setup -a 'filter=ansible_mem*' -
To get a variable from
ansible_facts, no need to writeansible_facts.var_nameasansible_factsis available to all during runtime. -
We can create custom facts in any language, the only thing is that it should return either a
jsonorinistructure. Accessible underansible_locali.e.ansible centos1 -m setup -a 'filter=ansible_local'. -
By default, expects to use
/etc/ansible/facts.d.
[!INFO] To refresh the facts do:
Now, the defaultfacts.ddirectory requires root access. To specify or refresh using custom facts directory, do:[!TIP] We can also use jinja2 templating inside
msgunderdebug
Syntax Check
- We can verify the syntax of playbook using --syntax-check directive.
ansible-playbook playbook.yaml --syntax-check
Step Run
- We can make the playbook runs user dependent by --step directive. Asks for each step to proceed or not.
High verbosity
- We can increase the verbose level using -vvvv arg.
ansible-playbook -vvvv playbook.yaml.
Pausing - We can pause the playbook for specified seconds:
- We can also have a prompt:
Waiting
- We can use
wait_formodule for waiting on some condition:
Playbook Register
- captures the task output.
---
-
hosts: linux
tasks:
- name: Exploring register
command: ls /home/
register: list_home_dir
ignore_errors: true # ignores this step if error occurs here
- name: List home dir
debug:
var: list_home_dir
...
[!INFO] Can also do
list_home_dir.stdoutinvarfor just output.
Playbook Loops
- There are many ways to implement loops.
item loop - item keyword is used for the value of each loop iteration.
- Can also pass contents as list:
- There is also
with_file.
Example 5 (running a script)
---
-
hosts: linux
tasks:
- name: Run a script until we hit 10
script: random.sh
register: result
retries: 100
until: result.stdout.find("10") != -1
delay: 1
...
Blocks
- Various one's in single block.
---
-
hosts: linux
tasks:
- name: A block of modules being executed
block:
- name: Example 1 CentOS only
debug:
msg: Example 1 CentOS only
when: ansible_distribution == 'CentOS'
- name: Example 2 Ubuntu only
debug:
msg: Example 2 Ubuntu only
when: ansible_distribution == 'Ubuntu'
- name: Example 3 with items
debug:
msg: "Example 3 with items - {{ item }}"
with_items: ['x', 'y', 'z']
...
Ansible Vault
- For encrypting vars, files.
To encrypt
ansible-vault encrypt_string --ask-vault-pass --name 'ansible_become_pass' 'password'
To use
ansible --ask-vault-pass ubuntu -m ping -o
Encrypt vars.yaml
ansible-vault encrypt external_vars.yaml
Decrypt
ansible-vault decrypt external_vars.yaml
Ansible Playbook structure
include_tasks
---
-
hosts: all
tasks:
- name: Play 1 - Task 1
debug:
msg: Play 1 - Task 1
- include_tasks: play1_task2.yaml # this file only contains name
...
play1_task2.yaml
Playbook tags
- Can be used to run a specific task by specifying tag name.
---
-
hosts: linux
vars_files:
- vars/logos.yaml
tasks:
- name: Install EPEL
yum:
name: epel-release
update_cache: yes
state: latest
when: ansible_distribution == 'CentOS'
tags:
- install-epel
- name: Install Nginx
package:
name: nginx
state: latest
tags:
- install-nginx
- name: Restart nginx
service:
name: nginx
state: restarted
notify: Check HTTP Service
tags:
- restart-nginx
- name: Template index.html-easter_egg.j2 to index.html on target
template:
src: index.html-easter_egg.j2
dest: "{{ nginx_root_location }}/index.html"
mode: 0644
tags:
- deploy-app
- name: Install unzip
package:
name: unzip
state: latest
- name: Unarchive playbook stacker game
unarchive:
src: playbook_stacker.zip
dest: "{{ nginx_root_location }}"
mode: 0755
tags:
- deploy-app
handlers:
- name: Check HTTP Service
uri:
url: http://{{ ansible_default_ipv4.address }}
status_code: 200
...
Run by: ansible-playbook playbook.yaml --tags "install-nginx"
Ansible Roles
- Better way of doing ansibling.
- Initiate a role using:
ansible-galaxy init <role-name>. - To use role inside a playbook, write the role name under Roles.
---
-
hosts: all
roles:
- nginx # role
tasks:
- name: Play 1 - Task 1
debug:
msg: Play 1 - Task 1
- include_tasks: play1_task2.yaml # this file only contains name
...
meta/main.yml- This contains meta info.
- We can also specify a dependency of the current role on another role by specifying the other role under
dependencieskey.
become & become_user
becomeis thesudoequivalent in ansible.-
become_useris the user to become; not the one to login as. -
To enter the sudo password interactively, use
-Karg:
ansible-playbook x.yaml -K
[!IMPORTANT] For use with docker, see Ansible with Docker.
Example 5 (Roles + Docker)
1) Create a role using ansible-galaxy init docker.
2) Under tasks, create three files: (main.yml will be the default one)
- dockerImageDelete.yml
- dockerContainer.yml
- dockerPull.yml
dockerImageDelete.yml
---
- name: Docker Image Delete
docker_image:
name: centos
state: absent
register: image_delete
- name: Debug message
debug:
var: image_delete["actions"]
...
dockerContainer.yml
---
- name: Create centos container
docker_container:
name: containercentos
image: centos
ports:
- 4287:80
state: started
container_default_behavior: no_defaults
register: container_start
- name: Debug message
debug:
var: container_start
...
dockerPull.yml
---
- name: Pulling the docker image
docker_image:
name: centos
source: pull
register: image_pull
- name: Debug message
debug:
var: image_pull["actions"]
...
3) The above can be reference in the main.yml file as:
---
- name: Pull docker image on the remote servers
import_tasks: dockerPull.yml
when: docker_input == "1"
- name: Delete docker image on the remote servers
import_tasks: dockerImageDelete.yml
when: docker_input == "2"
- name: Start the docker container
import_tasks: dockerContainer.yml
when: docker_input == "3"
...
4) Alongside the role folder docker, create a playbook and include the following:
---
-
hosts: localhost
connection: local
become: yes
become_user: root
vars_prompt:
- name: docker_input
prompt: "1) pull\n2) delete\n3) start"
private: False
roles:
- docker
...
[!NOTE] We can also build using Dockerfile. The concept remains the same. Just keep in mind that the project directory location should be relative to the directory from where
ansible-playbookis being run.
Example 6 (AWS EC2 + Ansible)
1) Make sure that the credentials are configured inside ~/.aws/credentials.
2) Better to use IAM Identity Centre now-a-days. Just create the user there, and configure in the terminal using aws configure sso.
3) Now, we can either have a static inventory or dyanmic inventory. For dynamic one, create a new inventory file: aws_ec2.yaml and add it to inventory directory.
4) Create hosts under inventory and add it as a default inventory to ansible.cfg.
hosts
ansible.cfg
aws_ec2.yaml
---
plugin: amazon.aws.aws_ec2
aws_profile: test-ec2
hostnames:
- ip-address
regions:
- us-east-1
groups:
ansible: "'urlShortenerServer' in tags.Ansible"
...
5) Run with: ansible-inventory -i aws_ec2.yaml --list/--graph.
keyed_groups vs groups
- groups is another way when we know info before hand. Suppose we know the tags of ec2 instances, then we can create our own group.
---
plugin: amazon.aws.aws_ec2
aws_profile: test-ec2
hostnames:
- ip-address
regions:
- us-east-1
groups:
redhat: "'redhat' in tags.OS"
ubuntu: "'ubuntu' in tags.OS"
...
6) After configuring sso using aws configure sso, for using the profile just put the configured name in the aws_profile section in ansible.
[!NOTE] It may happen that the credentials expire after the specified time. Just do
aws configure sso-sessionand then justaws sso login --sso-session <session-name>.[!IMPORTANT] It may also happen that after doing the above, the ansible is still saying
credentials expired. It may be that therootuser on the system may have the oldcredentials. Just run theconfigurecommands inroot.
7) Also create a key-pair in aws for connecting to the ec2 instance.
8) Do chmod 600 key.pem for securing it otherwise there'll be an error while ssh'in.
9) Now when we run any playbook using aws_ec2.yaml as inventory, an in-memory group will be formed for which we can beforehand specify some group vars under group_vars directory. The in-memory group will be ansible, so:
ansible
---
ansible_ssh_private_key_file: ansible.pem
ansible_user: ubuntu
ansible_become: true
#ansible_ssh_common_args: '-o StrictHostKeyChecking=no' # not in prod
# docker_github_token: !vault |
# $ANSIBLE_VAULT;1.1;AES256
# 61333462616136663461316334366130633061393365383763633936616233646334343833666437
# 6465386231656632353038343631333464313533623133330a326230666663366236616337626238
# 63376531323461303935616133653936306630383463666265386236313739633165396634323731
# 3164643166613230630a363361363532323139353837353532663464386631383731353561316165
# 65303061363465653963303662393432633563363736333863626365396532333236336634313031
# 3365373731373437663830623434363332633532636662326231
...
[!NOTE] Make sure that the
ansible.pemis in the same directory.
localhost_group.yaml
---
become: true
become_user: root
connection: local
#github_token: !vault |
# $ANSIBLE_VAULT;1.1;AES256
# 33366266353635346265376534613339663633386131666337363739633831353962633639383431
# 6333316538313163393337663462613032363766666464660a303838613531326164316432626366
# 36326132633365623734303566643838616261303436663264303731633231363737323438336336
# 3230386638623763350a346664343861396533363836663135633735316330383466343365386564
# 38646235613533656131343862313763653339313730313737616530373937323566326334353932
# 3866663537373337393535313432303061326236616432653633
...
10) We can also have a localhost.yaml under host_vars:
localhost.yaml
---
ansible_become: true
ansible_connection: local
#github_token: !vault |
# $ANSIBLE_VAULT;1.1;AES256
# 33366266353635346265376534613339663633386131666337363739633831353962633639383431
# 6333316538313163393337663462613032363766666464660a303838613531326164316432626366
# 36326132633365623734303566643838616261303436663264303731633231363737323438336336
# 3230386638623763350a346664343861396533363836663135633735316330383466343365386564
# 38646235613533656131343862313763653339313730313737616530373937323566326334353932
# 3866663537373337393535313432303061326236616432653633
...
11) Now, following is the playbook for creating ec2.
1_create_ec2.yaml
---
-
name: Create EC2 instances
hosts: localhost
become: true
connection: local
gather_facts: false
vars_prompt:
- name: aws_profile
prompt: "Enter aws profile: "
private: false
- name: region
prompt: "Enter region: "
private: false
default: us-east-1
- name: sec_group
prompt: "Enter security group id: "
private: false
# default: "sg-012wxxxxx"
- name: sg_desc
prompt: "Desc about Security Group: "
private: false
default: Custom Security Group
- name: image
prompt: "Enter ami-id: "
private: false
default: ami-080e1f13689e07408 # ubuntu
- name: instance_type
prompt: "Enter instance type: "
private: false
default: t2.micro
- name: key_name
prompt: "Enter key name: "
private: false
default: ansible
- name: count
prompt: "Enter count of instances: "
private: false
default: 1
tasks:
- name: Create Security Group
amazon.aws.ec2_security_group:
name: "{{ sec_group }}"
description: "{{ sg_desc }}"
region: "{{ region }}"
aws_profile: "{{ aws_profile }}"
rules:
- proto: tcp
ports:
- 22
cidr_ip: 0.0.0.0/0
rule_desc: allow_ssh
- proto: tcp
ports:
- 3000
cidr_ip: 0.0.0.0/0
rule_desc: frontend-exposed
- name: Create an instance
amazon.aws.ec2_instance:
key_name: "{{ key_name }}"
aws_profile: "{{ aws_profile }}"
instance_type: "{{ instance_type }}"
region: "{{ region }}"
image_id: "{{ image }}"
security_group: "{{ sec_group }}"
network:
assign_public_ip: true
wait: true
exact_count: "{{ count }}"
tags:
Ansible: urlShortenerServer
...
12) Now, run the following using -i inventory/aws_ec2.yaml for configuring ec2 instances.
2_configure_ec2.yaml
---
- name: Configure EC2 instance
hosts: ansible
connection: ssh
become: true
tasks:
- name: Update the machine
command: sudo apt-get clean && update -y
- name: Installing essentials
command: apt-get install apt-transport-https ca-certificates curl software-properties-common -y
- name: Installing Curl
command: apt-get install curl -y
- name: Pre-steps
command: "{{ item }}"
with_items:
- curl -fsSL https://get.docker.com -o get-docker.sh
- sudo sh get-docker.sh
- name: Adding user to group
command: sudo usermod -aG docker ${USER}
- name: Restarting docker service
command: sudo service docker restart
- name: Updating the machine 2
command: sudo apt-get update
- name: Installing Python Pip
command: sudo apt-get install python-pip -y
- name: Installing Docker compose
command: sudo apt-get install docker-compose-plugin
...
13) Now a role called docker is created using ansible-galaxy init docker. Variables are defined under vars and are prefixed with the role name docker_:
---
# vars file for docker
docker_script_dest: ./
docker_github_token: !vault |
$ANSIBLE_VAULT;1.1;AES256
61333462616136663461316334366130633061393365383763633936616233646334343833666437
6465386231656632353038343631333464313533623133330a326230666663366236616337626238
63376531323461303935616133653936306630383463666265386236313739633165396634323731
3164643166613230630a363361363532323139353837353532663464386631383731353561316165
65303061363465653963303662393432633563363736333863626365396532333236336634313031
3365373731373437663830623434363332633532636662326231
...
[!NOTE] The
docker_github_tokenis encrypted usingansible-vault encrypt_string <string>.
14) There are 3 tasks under tasks directory:
main.yaml
---
- name: Copying the required files
ansible.builtin.import_tasks: setup_files.yaml
- name: Running Docker Compose
ansible.builtin.import_tasks: docker_compose.yaml
- name: Copying env files
ansible.builtin.import_tasks: copy_env.yaml
...
setup_files.yaml
---
- name: Getting the required files
block:
- name: Copying the script
ansible.builtin.copy:
src: get_files.sh # auto taken from files directory
dest: "{{ docker_script_dest }}"
mode: '0644'
register: copy_output
when: docker_input == "1"
- name: Running the script
ansible.builtin.script: "{{ docker_script_dest }}get_files.sh {{ docker_github_token }}"
register: script_result
when: docker_input == "1"
- name: Install pip
command: sudo apt-get install python3-pip -y
when: docker_input == "1"
- name: Install docker python
command: pip install docker==6.1.3 # only this works
when: docker_input == "1"
- name: Install docker-compose python package
ansible.builtin.pip:
name: docker-compose
when: docker_input == "1"
- name: Debug Output
ansible.builtin.debug:
var:
- copy_output
- script_result
...
docker_compose.yaml
---
- name: Docker Compose for Frontend + Backend
community.docker.docker_compose:
# project_name: frontend_+_backend
project_src: url-shortener/url-shortener/frontend-servers/
when: docker_input == "2"
register: output
- name: Docker compose remove containers
community.docker.docker_compose:
project_src: url-shortener/url-shortener/frontend-servers/
state: absent
when: docker_input == "3"
- name: Docker Compose Status
ansible.builtin.debug:
var: output # its something else here
...
- Have the respective folders under files for
.envfiles as specified in the below code:
copy_env.yaml
---
- name: Copying .env's
block:
- name: Copying frontend .env
ansible.builtin.copy:
src: frontend/.env
dest: url-shortener/url-shortener/frontend/
mode: '0644'
register: frontend_copy
when: docker_input == "4"
- name: Copying go server .env
ansible.builtin.copy:
src: go/.env
dest: url-shortener/url-shortener/servers/go/
mode: '0644'
register: go_copy
when: docker_input == "4"
- name: Copying express js .env
ansible.builtin.copy:
src: express_js/.env
dest: url-shortener/url-shortener/servers/express-js
mode: '0644'
register: express_copy
when: docker_input == "4"
- name: Debug Output
ansible.builtin.debug:
var:
- frontend_copy
- go_copy
- express_copy
...
15) Then we run the above using the following playbook:
3_docker_book.yaml
---
-
name: Setting up and running docker compose
hosts: ansible
#connection: local
become: yes
#become_user: root
vars_prompt:
- name: docker_input
prompt: "1) Setup Files\n2) Compose up\n3) Compose rm\n4) Copy .env files"
private: False
roles:
- docker
...
16) > [!NOTE] Make sure that there are 3 dirs under files in docker named frontend, go and express_js containing .env files, if they need to be copied to the remote servers.
17) Now, to start everything up, run the following commands:
- ansible-playbook 1_create_ec2.yaml -K
- ansible-playbook -i inventory/aws_ec2.yaml 2_configure_ec2.yaml
- ansible-playbook -i inventory/aws_ec2.yaml 3_docker_book.yaml
[!NOTE] Make sure that
.envfiles are copied or set up there on the remote servers for my projecturl shortenerotherwisedocker-composewill not work.[!IMPORTANT] In order to avoid
ansible-lintcheck on a specific line, copy the error code like yaml[something-something] and put it in front of the line as:# noqa error-here.