Ansible Tutorial
This will try to walk you through the setup and using ansible.
Brief Overview
I consider ansible just another python tool that is trying to solve configuration management of servers and services. While it is not perfect it does provide a pretty good level of abstraction for managing DevOps. These tools will always continue to involve and who knows what I will be using tomorrow but the concepts usually stay the same:
- provide an immutable state to describe infrastructure and software
- be able to managing with git
- reproducibility
- scalability
Where do these tools fall short
I would say there is a pretty big learning curve regardless of the tools you are using. Most DevOps people know docker but most developers do not. To take it one step further DevOps is usually manging resource allocation either in the cloud or in a data center. Ansible while provides a layer on top of these the complexity can soon consume 100% of the time trying to “get it to work” as I call it. I have written many tools like ansible using fabric python library. That said I do understand the need for tools like ansible where we have a common language (yml) to describe our steup. Infrastructure as code.
Some Advangages I see with Ansible
Ansible has no client so this is always a push based system. Everything is driven through SSH access as it should be. I prefer to even take it one step further and always use private/public keys. Many companies though are running active directory services to provide access to these servers. We will see later on how to manage either setup.
2 types of servers
Control machine is a machine with the ansible software configured in order to manage nodes. Nodes are machines controled by the control machine. The control machine can simple be a laptop or a jenkins server in the clould. Lets create a docker file for this so we can easily have these tools ran anywhere that supports docker.
Copy a new private/public key pair into place as id_rsa  id_rsa.pub  I won’t include these in the
tutorial.
Dockerfile-control
FROM ubuntu:20.04
# time docker build . -t thesheff17/ansible-control -f Dockerfile-control
RUN  echo 'Acquire::http { Proxy "http://172.17.0.2:3142"; };' >> /etc/apt/apt.conf.d/01proxy
RUN \
    apt-get update && \
    apt-get upgrade -y && \
    export DEBIAN_FRONTEND=noninteractive && \
    apt-get install -y python3 python3-pip python3-dev tmux vim build-essential git wget ssh \
    iputils-ping net-tools && \
    apt-get autoremove && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
COPY id_rsa /root/.ssh/
COPY id_rsa.pub /root/.ssh/
RUN \
    pip3 install ansible bpython awscli && \
    cd /root/ && \
    wget https://raw.githubusercontent.com/thesheff17/dotfiles/master/.tmux.conf && \
    wget https://raw.githubusercontent.com/thesheff17/vim/master/vimrc && \
    mv vimrc .vimrc && \
    mkdir /var/run/sshd && \
    mkdir /etc/ansible && \
    yes | unminimize
COPY hosts /etc/ansible/
COPY ansible.cfg /etc/ansible/
COPY pingAll.sh /root/
COPY apache2.yml /root/
# if you need to generate another key
# ssh-keygen -t rsa -b 4096 -N "" -f ~/.ssh/id_rsa && \
# cat /root/.ssh/id_rsa.pub
EXPOSE 22
CMD ["/bin/bash"]
hosts
[webserver]
172.17.0.3
172.17.0.4
172.17.0.5
172.17.0.6
ansible.cfg
[defaults]
host_key_checking = False
pingAll.sh
#!/bin/bash
ansible all -m ping
apache2.yml
---
- hosts: webserver
  tasks:
    - name: install apache2
      apt: name=apache2 update_cache=yes state=latest
    - name: enabled mod_rewrite
      apache2_module: name=rewrite state=present
      notify:
        - restart apache2
  handlers:
    - name: restart apache2
      service: name=apache2 state=restarted
...
Dockerfile-node
FROM ubuntu:20.04
# time docker build . -t thesheff17/ansible-node -f Dockerfile-node
# docker run -d -P --name server1 thesheff17/ansible-node:latest
# docker run -d -P --name server2 thesheff17/ansible-node:latest
#
RUN  echo 'Acquire::http { Proxy "http://172.17.0.2:3142"; };' >> /etc/apt/apt.conf.d/01proxy
RUN \
    apt-get update && \
    apt-get upgrade -y && \
    export DEBIAN_FRONTEND=noninteractive && \
    apt-get install -y tmux vim ssh && \
    apt-get autoremove && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN \
    cd /root/ && \
    wget https://raw.githubusercontent.com/thesheff17/dotfiles/master/.tmux.conf && \
    wget https://raw.githubusercontent.com/thesheff17/vim/master/vimrc && \
    mv vimrc .vimrc && \
    mkdir /var/run/sshd
COPY id_rsa.pub /root/.ssh/authorized_keys
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
build.sh - helper script to build images:
#!/bin/bash
echo "build.sh started..."
time docker build . -t thesheff17/ansible-control -f Dockerfile-control
time docker build . -t thesheff17/ansible-node -f Dockerfile-node
docker run -d -P --name server1 thesheff17/ansible-node:latest
docker run -d -P --name server2 thesheff17/ansible-node:latest
docker run -d -P --name server3 thesheff17/ansible-node:latest
docker run -d -P --name server4 thesheff17/ansible-node:latest
echo "build.sh completed."
You can call build.sh and it will stand up 4 the nodes.  You can then connect to the control
ansible container and run pingAll.sh and this should ping every host.  Lets also get the uptime
for every node in the webservers header: ansible webservers -m command -a "uptime"
ansible webserver -m command -a "uptime"
172.17.0.3 | CHANGED | rc=0 >>
12:00:49 up  9:10,  1 user,  load average: 0.00, 0.01, 0.06
172.17.0.5 | CHANGED | rc=0 >>
12:00:49 up  9:10,  1 user,  load average: 0.00, 0.01, 0.06
172.17.0.4 | CHANGED | rc=0 >>
12:00:49 up  9:10,  1 user,  load average: 0.00, 0.01, 0.06
172.17.0.6 | CHANGED | rc=0 >>
12:00:49 up  9:10,  1 user,  load average: 0.00, 0.01, 0.06
Now that we have ansible controlling our webservers lets install apache2.  Add this to apache2.yml
---
- hosts: webserver
  tasks:
    - name: install apache2
      apt: name=apache2 update_cache=yes state=latest
    - name: enabled mod_rewrite
      apache2_module: name=rewrite state=present
      notify:
        - restart apache2
  handlers:
    - name: restart apache2
      service: name=apache2 state=restarted
...
ansible-playbook apache2.yml
output:
ansible-playbook apache2.yml
PLAY [webserver] ************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************
ok: [172.17.0.5]
ok: [172.17.0.3]
ok: [172.17.0.6]
ok: [172.17.0.4]
TASK [install apache2] ******************************************************************************************************
[WARNING]: Updating cache and auto-installing missing dependency: python3-apt
changed: [172.17.0.3]
changed: [172.17.0.5]
changed: [172.17.0.4]
changed: [172.17.0.6]
TASK [enabled mod_rewrite] **************************************************************************************************
changed: [172.17.0.5]
changed: [172.17.0.6]
changed: [172.17.0.3]
changed: [172.17.0.4]
RUNNING HANDLER [restart apache2] *******************************************************************************************
changed: [172.17.0.3]
changed: [172.17.0.4]
changed: [172.17.0.6]
changed: [172.17.0.5]
PLAY RECAP ******************************************************************************************************************
172.17.0.3                 : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
172.17.0.4                 : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
172.17.0.5                 : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
172.17.0.6                 : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Now you have a cluster of apache2 server running. You can now start working on any other services you need to define in ansible. Where do you go from here? Well I recommend starting with the documenation on parts you are unfamiliar with. Learn about vaults modules to start with. Youtube/Google are also great resources for finding good free ansible examples. There are certainly allot better examples out there of install and configurating apache2, nginx, and so on. I show just enough to understand what ansible + ssh can do. If you need a boost in speed as playbooks get longer check out mitogen.