Category: ansible

Install Ansible for Ubuntu

Install Ansible for Ubuntu

Install pip

Check pip installed

python3 -m pip -V

Install pip using root

apt install python3-pip

Install ansible

Install ansible using normal user

python3 -m pip install --user ansible

Note: ignore the warning message about .local/bin, the folder will be created and will be in the path after re-login

Upgrade ansible

python3 -m pip install --upgrade --user ansible

References

Installing Ansible

Learning – Ansible 101 – Episode 3 – Introduction to Playbooks

Learning - Ansible 101 - Episode 3 - Introduction to Playbooks

Playbooks

Default module

The ansible command default module is command. So following commands are the same

ansible -i inventory multi -m command -a "date"
ansible -i inventory multi -a "date"

update_cache task

For idempotence, can update_cache task

Molecule

Testing Ansible roles using Molecule.

Background

Timeout

Timeout in 3600 seconds.

ansible -i inventory multi -b -B 3600 -P 0 -a "yum -y update"

Pulling time

Using -P for seconds

ansible -i inventory multi -b -B 3600 -P 0 -a "yum -y update"

Job ID

The result shows ansible job ID, which can be used to query in the server.

192.168.60.6 | CHANGED => {
    ...
    "ansible_job_id": "991487770448.3711",
    ...
    "results_file": "/root/.ansible_async/991487770448.3711",
    ...
}

Query by job id

ansible -i inventory db -b -m async_status -a "jid=991487770448.3711"

*Note: This will not show log or error of job"

Check log

ansible -i inventory multi -b -a "tail /var/log/messages"
ansible -i inventory multi -b -m shell -a "tail /var/log/messages | grep ansible-command | wc -l"

Cron

ansible -i inventory multi -b -m cron -a "name=something hour=4 job=/path/to/script.sh"
ansible -i inventory multi -b -m cron -a "name=something hour=4 job=/path/to/script.sh state=absent"

Git

ansible -i inventory multi -b -m git -a "repo=github_url_goes_here dest=/opt/app update=yes version=1.2.4"

Reuse SSH connection

Ansible configuration file ansible.cfg

[ssh_connection]
pipelining = True

Clean up

Destroy VMs

vagrant destroy -f

Playbooks

mkdir playbooks
cd playbooks

Inventory

[ec2]
35.175.148.144

[ec2:vars]
ansible_user=centos
ansible_ssh_private_key_file=~/.ssh/jeffgeerling_aws.pem

Create a shell script

shell-script.sh

# Install Apache.
yum install --quiet -y httpd httpd-devel
# Copy configuration files.
cp httpd.conf /etc/httpd/conf/httpd.conf
cp httpd-vhosts /etc/httpd/conf/httpd-vhosts.conf
# Start Apache and configure it to run at boot.
service httpd start
chconfig httpd on

Create playbook.yml

---
- name: Install Apache.
  hosts: all

  tasks:
    - name: Install Apache
      command: yum install --quiet -y httpd httpd-devel
    - name: Copy configuration files.
      command: >
        cp httpd.conf /etc/httpd/conf/httpd.conf
    - command: >
        cp httpd-vhosts /etc/httpd/conf/httpd-vhosts.conf
    - name: Start Apache and configure it to run at boot.
      command: service httpd start
    - command: chkconfig httpd on

or

---
- name: Install Apache.
  hosts: all

  tasks:
    - name: Install Apache
      shell: |
        yum install --quiet -y httpd httpd-devel
        cp httpd.conf /etc/httpd/conf/httpd.conf
        cp httpd-vhosts /etc/httpd/conf/httpd-vhosts.conf

    - name: Start Apache and configure it to run at boot.
      command: service httpd start
    - command: chkconfig httpd on

or

---
- name: Install Apache.
  hosts: all
  become: true

  tasks:
    - name: Install Apache
      yum:
        name:
          - httpd
          - httpd-devel
        state: present
      become: true
    - name: Copy configuration files.
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        owner: root
        group: root
        mode: 0644
      with_items:
        - src: httpd.conf
          dest: /etc/httpd/config/httpd.conf
        - src: httpd-vhosts.conf
          dest: /etc/httpd/conf/httpd-vhosts.conf

  - name: Make sure Apache is started now and at boot.
    service:
      name: httpd
      state: started
      enabled: true

    - command: >
        cp httpd-vhosts /etc/httpd/conf/httpd-vhosts.conf
    - name: Start Apache and configure it to run at boot.
      command: service httpd start
    - command: chkconfig httpd on

run on all nodes except one

ansible-playbook -i inventory multi --limit db
ansible-playbook -i inventory multi --limit=192.168.60.6
ansible-playbook -i inventory multi --limit="!:db"

List inventory

ansible-inventory --list i inventory

References

Ansible 101 - Episode 3 - Introduction to Playbooks

Learning – Ansible 101 – Episode 2 – Ad-hoc tasks and Inventory

Learning - Ansible 101 - Episode 2 - Ad-hoc tasks and Inventory

Run ad-hoc tasks using Ansible.

Vagrant Cloud

Vagrant init

vagrant init geerlingguy/centos7

Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.box = "geerlingguy/centos7"

  config.ssh.insert_key = false

  config.vm.synced_folder ".", "/vagrent", disabled: true

  config.vm.provider :virtualbox do |v|
    v.memory= 256
    v.linked_clone = true
  end

  # App server 1
  config.vm.define "app1" do |app|
    app.vm.hostname = "orc-app1.test"
    app.vm.network :private_network, ip: "192.168.60.4"
  end

  # App server 2
  config.vm.define "app2" do |app|
    app.vm.hostname = "orc-app2.test"
    app.vm.network :private_network, ip: "192.168.60.5"
  end

  # DB server
  config.vm.define "db" do |db|
    db.vm.hostname = "orc-db.test"
    db.vm.network :private_network, ip: "192.168.60.6"
  end
end
vagrant up

Create inventory file

# Application servers
[app]
192.168.60.4
192.168.60.5

# Database server
[db]
192.168.60.6

# Group has all the servers
[multi:children]
app
db

# Variable for all the servers
[multi:vars]
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key

Run Ansible

ansible multi -i inventory -a "hostname"

Note: accept host key if prompt, or change the .ssh/config file to ignore host key

To run one by one,

ansible multi -i inventory -a "hostname" -f 1

Run ansible to query configuration

ansible -i inventory db -m setup

Install NTP

ansible -i inventory multi -b -m yum -a "name=ntp state=present"

ansible -i inventory multi --become -m yum -a "name=ntp state=present"

Note: Run the second time, the status will be SUCCESS, not CHANGED

Ask for sudo password

ansible -i inventory multi -K -m yum -a "name=ntp state=present"

Note: for this image, the vagrant user has password vargent

Check service status

ansible -i inventory multi -b -m service -a "name=ntpd state=started enabled=yes"

Check service options

  • Use google search "ansible service module".

  • Use ansible-doc command

ansible-doc service

NTP commands

ansible -i inventory multi -b -a "service ntpd stop"
ansible -i inventory multi -b -a "ntpdate -q 0.rhel.pool.ntp.org"

my_sql

Setup user on mysql server.

ansible -i inventory db -b -m mysql_user -a "name=django host=% password=12345 priv=*.*:ALL state=present"

Limit to one server

ansible -i inventory multi -a "free -m" --limit '192.168.60.4'
ansible -i inventory multi -a "free -m" --limit '*.4'
ansible -i inventory multi -a "free -m" --limit '!192.168.60.4'
ansible -i inventory multi -a "free -m" --limit '!192.168.60.4:!192.168.60.5'

References

Ansible 101 - Episode 2 - Ad-hoc tasks and Inventory

Learning – Ansible 101 – Episode 1 – Introduction to Ansible

Learning - Ansible 101 - Episode 1 - Introduction to Ansible

Introduction to Ansible

Installation

pip3 install ansible
ansible --version

Create inventory file

Create a file called inventory

[example]
107.20.106.183

Run command

ansible -i inventory example -m ping -u centos

Create ansible.cfg file

[defaults]
INVENTORY=inventory

Run command with not inventory option

ansible example -m ping -u centos

Run ad-hoc commnad

ansible example -a "date" -u centos
ansible example -a "free -h" -u centos

In fact, above commands used default module -m command, and the -a option is giving the command arguments.

Install VirtualBox and Vagrant

Then initialize vagrant

vagrant init geerlingguy/centos7

This will create a file called Vagrantfile in current directory.

Vargent VM commands

  • create vm
vagrant up
  • ssh into vm
vagrant ssh
  • show ssh configuration
vagrant ssh-config

This configuration can be used to update ssh configuration

  • shutdown vm
vagrant halt
  • delete vm
vagrant destroy

Create Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.box = "geerlingguy/centos7"

  config.vm.provsion "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
  end
end

Create playbook.yml

---
- name: Set up NTP on all servers.
  hosts: all
  become: yes
  tasks:
    - name: Ensure NTP is installed.
      yum: name=ntp state=present
    - name: Ensure NTP is running.
      service: name=ntpd state=started enabled=yes

The name is optional

    - yum: name=ntp state=present
    - service: name=ntpd state=started enabled=yes

Run provision command

vagrant provision

Idempotence

The command can be run many times without change the result if success before.

But following command in playbook will run every time when triggered playbook.

  - command: yum install -y ntp

To overcome this, change to following

  - shell: |
      if ! rpm -qa | grep -qw ntp; then
        yum install -y ntp
      fi

References

Ansible 101 - Episode 1 - Introduction to Ansible

Learning – Ansible Quick Start

Learning - Ansible - Quick Start

Install (CentOS)

yum update -y
yum install epel-release -y
yum install ansible -y

Add managed hosts

Add following line in /etc/ansible/hosts

[linux]

45.56.72.153
45.79.56.223

[linux:vars]

ansible_user=root
ansible_password=P@ssword123

Disable host key checking

Edit ansible.cfg file as below

host_key_checking = false

Run module

ping

ansible linux -m ping

Run ad hoc command

ansible linux -a "cat /etc/os-release"
ansible linux -a "reboot"

Playbook

Playbook => Plays => Tasks

Servers

For example, following yaml file iluvnano.yml

---
  - name: iluvnano
    host: linux
    tasks:
      - name: ensure nano is there
        yum:
          name: nano
          state: latest

The ilvunano is Play, the ensure nano is there is Task.

Run playbook

ansible-playbook iluvnano.yml

If change the state to absent in iluvnano.ymland rerun above command, the nano will be removed.

Routers

In /etc/ansible/hosts file

[routers]

ios-xe-mgmt-latest.cisco.com
ios-xe-mgmt.cisco.com

[routes:vars]

ansible_user=developer
ansible_password=C1sco12345
ansible_connection=network_cli
ansible_network_os=ios
ansible_port=8181

In /etc/ansible/ansible.cfg

host_key_checking = false

Run commands

ansible routers -m ping
ansible routers -m ios_command -a "commands='show ip int brief'"

Playbook devnet.yml

---
  - name: General Config
    hosts: routers
    tasks:
    - name: Add Banner
      ios_banner:
        banner: login
        text: |
          Nicolas Cage is the
          Tiger King
        state: present
      - name: Add loopback
        ios_interface:
          name: Loopback21
          state: present

Run following command

ansible-playbook devnet.yml

To remove the changes, update the state in yaml file

state: absent

Run following command again

ansible-playbook devnet.yml

Then the routers will be modified.

show ip int brief
show run | beg banner

References

you need to learn Ansible RIGHT NOW!! (Linux Automation)
get started with Ansible Network Automation (FREE cisco router lab)