Prerequisites
- I'm using windows8 and using virtual CentOS 7.3 in windows local as Ansible's host machine. If you don't have Linux or Mac, use virtual machine like I do. But in that case, don't forget to set the host's IP adress to 198.168.33.11 because duplicate IP causes an error.
- As such, we will use two virtual machines in Windows.
- Control node (CentOS7.3, IP:192.168.33.10).
- Managed nodes (Hosts) (CentOS7.3, IP:192.169.33.11).
See
here for virtual machines.
Install Ansible
At first, install python3.6 from IUS repository in Control node.
$ sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
$ sudo yum install -y python36u python36u-libs python36u-devel python36u-pip
And install ansible.
$ python3.6 -m pip install ansible
$ sudo yum install -y sshpass
And check if you have installed it successfully.
$ ansible --version
ansible 2.5.5
config file = None
configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.5 (default, Feb 6 2018, 10:57:32) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
We installed ansible from pip. So we don't have /etc/ansible/ansible.cfg. You can create the cfg file by yourself. The default file can be found in
their github. See
their documentation too.
Add hosts information
Run the following to create hosts file in Control node:
$ sudo mkdir /etc/ansible/
$ sudo vi /etc/ansible/hosts
Write as follows:
[mynodes]
192.168.33.11
And save and close it by pressing :wq.
Also run this command too:
$ sudo vi /etc/ansible/ansible.cfg
Then write as follows:
[defaults]
host_key_checking = true #different from before
Then save and close it.
Get a private/public key
If you want a pair of private/public key, run the following to get the key pair in Control node:
$ cd ~/.ssh
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (~/.ssh/id_rsa): # Just press enter key.
Enter passphrase (empty for no passphrase): # Just press enter key.
Enter same passphrase again: # Just press enter key.
Your identification has been saved in /home/vagrant/.ssh/id_rsa.
Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub.
The key fingerprint is:
6f:9d:ed:39:06:75:70:9b:ff:c0:71:51:ff:00:8a:dc vagrant@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
| . o|
| . o . ...o|
| o E .o=|
| o++|
| S o +o|
| . ..oo .|
| o o....|
| . .o..|
| .o. |
+-----------------+
$ ls .ssh
And you will get these files: authorized_keys, id_rsa, id_rsa.pub, known_hosts... Check the key:
$ ls ~/.ssh
$ cat ~/.ssh/id_rsa.pub
#Copy this!
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5MZHya9h3LwYux7Va+hA73M0T6JnjpUoLw/0jk073x3JWOu5pIPhlA+zxOUTu5A+5PRkkQH9EYK7Y+OlnW45FZppnRtZeS38SAJxsaM0WvfQorRJKDeZdIvb8TLEJIiFA9rJo98/U1fmqGY3KBMUTnYalGTj1rLmenjUpVi9Z8BKlxAfX5xojN7ZyhcFbp9gZUKg3USUTz+q6UsAT8tq4ZqIPz2f52+RpPumSf+cVxuqv5o4dsBxGQfyRGHEEPb4QYWyjdn6EzdNbjec4iqZ6XYVDu1nar+pCLU8Bz0MJoCe38tae2GeuvJgW5cgKJ6ZWk1GqWaEgLaJpwZqbuHMD vagrant@localhost.localdomain
Copy the long random letters. And paste it in the Managed nodes.
$ sudo vi ~/.ssh/authorized_keys
Like this:
then save and close it by :wq. (Other than using copy and paste, you can use also "scp" command and transfer the id_rsa.pub file to the hosts machine. It's difficult but worth checking.)
Try the ansible command
We will try the ansible command. But please note that you can't use sudo command in this case. Because the public key was not for the root. The public key was created for a user "vagrant". If you use sudo, you will be recognized as "root". So the command will be rejected by the Managed nodes.
Run this command in Control node:
$ ansible 192.168.33.10 -m ping
If you see this, you successfully did everything:
Example
Save the following as "test.yaml" in the vagrant shared folder /vagrant in Control node:
- hosts: mynodes
tasks:
- name: Update yum
become: yes
become_method: sudo
yum:
name: '*'
state: latest
- name: Install apache
become: yes
become_method: sudo
yum:
pkg: httpd
state: latest
update_cache: true
Then run the following command:
$ ansible-playbook /vagrant/test.yaml -u vagrant
"u" option specifies which user should be used. For other options, look at
this.
The developement environment will be automatically created in the hosts machine by ansible.
You can explicitly specify where the hosts file is:
$ ansible-playbook /vagrant/php.yaml -u vagrant -i /etc/ansible/hosts
If the hosts file is somewhere else.
Use module
This is an example of using file
module:
- hosts: mynodes
tasks:
- name: Make a test file. Directory too if not exist.
file: # File module here!!
path: /tmp/test
owner: vagrant
group: vagrant
state: directory
mode: 0755
See
here for the detail of File module. You can easily use modules in playbook.
Run the playbook.
$ ansible-playbook /vagrant/test2.yml -u vagrant -i /etc/ansible/hosts
Result:
You can see the directory /tmp/test is created in managed nodes (i.e. mynodes):
If you want to run the commands with super user priviledge:
- hosts: mynodes
tasks:
- name: Make a test file. Directory too if not exist.
become: yes
become_method: sudo
file:
path: /etc/test
owner: vagrant
group: vagrant
state: directory
mode: 0755
Develop modules on your own
Roles
Now we know how to write a playbook. But what if we make a lot of tasks? The playbook would be too long and impossible to reuse for future solutions. This is where we must use roles and separate the tasks into smaller files.
This is an example of a directory when we use Roles
.
test.yml
roles/
apache2/
tasks/
The tasks
directory s mandatory, but we can use the following directories too other than tasks
:
test.yml
roles/
apache2/
files/
templates/
tasks/
handlers/
vars/
defaults/
meta/
- tasks: contains the main list of tasks to be executed by the role.
- handlers: contains handlers, which may be used by this role or even anywhere outside this role.
- defaults: default variables for the role (see Using Variables for more information).
- vars: other variables for the role (see Using Variables for more information).
- files: contains files which can be deployed via this role.
- templates: contains templates which can be deployed via this role.
- meta: defines some meta data for this role. See below for more details.
We will use only tasks
in this post.
Example
At first, create roles
and apache
directory and create necessary files in Control node:
$ mkdir -p /vagrant/roles/apache/tasks
$ touch /vagrant/test3.yml
$ touch /vagrant/roles/apache/tasks/main.yml
$ touch /vagrant/roles/apache/tasks/debian.yml
$ touch /vagrant/roles/apache/tasks/redhat.yml
Then write as follows respectively:
test3.yml
- hosts: mynodes
become: yes
become_method: sudo
remote_user: "vagrant"
roles:
- apache
main.yml
# you can have any generic tasks directly in main.yml
- name: get the date
shell: "date"
register: date
# you can directly write non-generic tasks here too.
#- name: Install apache2 (RedHat).
# yum: name=httpd
# when: "ansible_os_family == 'RedHat'"
#- name: Install apache2 (Debian).
# apt: name=apache2
# when: "ansible_os_family == 'Debian'"
# or include files
- include: debian.yml
when: ansible_os_family == 'Debian'
- include: redhat.yml
when: ansible_os_family == 'RedHat'
debian.yml
- name: install apache
apt:
state: latest
update_cache: true
name:
- httpd
redhat.yml
- name: install apache
yum:
state: latest
update_cache: true
name:
- httpd
Run the example
Run the example:
$ ansible-playbook /vagrant/test3.yml -u vagrant -i /etc/ansible/hosts
Result: