Talk:Ansible: Difference between revisions

From Network Security Wiki
Content added Content deleted
No edit summary
 
(33 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Features of Ansible =
* Ansible is Modular
* 1000+ Modules available.
* 1000+ Modules available.
* Modules written in python.
* Modules written in python.

= Running Ansible =
* Do not use Root account for ansible
* Create an account with all privileges:

sudo visudo
%ansible ALL=(ALL) ALL
usermod -aG ansible aman

* Install python on all hosts:
yum install -y python2 epel-release

* Add entry to Hosts file & enable key less SSH access:
ssh-copy-id -i ~/.ssh/id_rsa.pub aman@server2

* Using the same username is convenient but not required.


= Inventory file =
= Inventory file =
Line 10: Line 29:
controller.example.com
controller.example.com
node1.example.com
node1.example.com

[servers]
node1.example.com
server1.example.com

ansible all -i inventory --list-hosts

= Ansible Config File =

*Variour ansible.cfg files:
/etc/ansible/ansible.cfg
~/.ansible.cfg
ansible.cfg in project directory (takes precedence)

*Contents:
become: Specify how to escalate privileges on the managed host.
become_user: Specify which user account to use on remote host.
become_ask_pass: Whether or not a password should be asked.
inventory: Which Inventory files to be used.
remote_user: Name of user account on the managed host. Not set by default, so local username is used.

*Privilege Escalation

Ansible runs tasks on managed host using same user account as local user, so make sure to copy ssh keys.
Set remote_user in ansible.cfg to specify another user to be used.
If remote_user is not specified, Privilege Escalation can be used.
Enable in [privilege_escalation] section in ansible.cfg:
become=True
become_method=sudo
become_user=root
become_ask_pass=False
Privilege escalation needs sudo configuration
Create a sudo file on all Ansible managed hosts:
nano /etc/sudoers.d/user
user ALL=(ALL) NOPASSWD: ALL

= Adhoc Commands =

* Used for Diagnostics like querying a large number of hosts.
* To quickly make changes to many managed hosts
* Modules are used:
-m Specifies Modules
-a Specifies Arguments
* Default Module can be set in ansible.cfg file.
* 3 Adhoc commands:
command: runs command on managed host
shell: runs command on managed host through the local shell
copy: copy a file, change content on a remote host in a target file

ansible all -i inventory -m command -a id
ansible all -i inventory -m command -a id -o
ansible all -i inventory -m command -a env
ansible all -i inventory -m shell -a env
ansible server1 -m copy -a 'content="Ansible Managed\n" dest=/etc/motd'

= Modules =

List Modules:
ansible-doc -l

Module Help:
ansible-doc <modulesname>

Create sample config:
ansible-doc -s <modulesname>

Using Modules:
ansible all -i inventory -m ping
ansible -i inventory -m ping all

Using in Playbooks:

<pre>
tasks:
- name: Install a package
yum:
name: vsftpd
state: latest
</pre>

= YAML =
* YAML(YAML Ain't Markup Language) structures are represented by indentation.
* Data elements at same hierarchy level should be at same indentation level.
* Do not use Tabs for indentation.
* It is common but not mandatory to start YAML file with 3 dashes & end it with 3 dots.
* This allows YAML code to be placed in some other code.

* Example:
<pre>
---
# example playbook
item1:
parameter1
parameter2
option1
option2
item2
parameter3
...
</pre>

== YAML Contents ==

* Dictionary: key/value pair written in key: value notation
* Lists: represent a list of items, enumerated as '''- item'''. Space after - is mandatory.
* Strings can be enclosed in single or double quotes but that is not mandatory.
* In a multi-line string, first line is ended by | or >. Next lines are indented.
* Verify YAML syntax:
ansible-playbook --syntax-check mycode.yaml

* Dry Run:
ansible-playbook -C mycode.yaml
* Step-by-Step:
ansible-playbook --step mycode.yaml

= Playbook =

* Tasks are performed by Modules.
* Ordering is important: Plays & Tasks are executed in the order they are presented.
* Playbooks do not change anything if the host is already in desired state.
* Avoid modules like command, shell & raw as they are not idempotent by nature.

== Task Attribute ==

* Most important Attribute is Task attribute:

<pre>
tasks:
- name: run service
service: name=vsftpd enabled=true
</pre>

* Here '-' marks beginning of a list of attributes.
* If multiple tasks are defined, each first attribute of task starts with '-'.

== Other Attributes ==

name: specify a specific label to play
hosts: uses patterns to define on which hosts to run a play
remote_user: overwrites the remote_user setting in ansible.cfg
become: overwrites the become setting in ansible.cfg
become_method: overwrites the become_method setting in ansible.cfg
become_user: overwrites the become_user setting in ansible.cfg

= Variables =

* Used for repeated tasks like:
Creating users
Removing files
Installing packages
* Names must start with letters
* Can be defined at a lot of levels
* Can be defined with different scope:
Global Scope: Set from CLI or ansible configuration file
Play Scope: Defined in playbook
Host Scope: Set on groups or Individual hosts through inventory file.
* Variables defined at highest level wins: Global scope wins from host scope

== Defining Variables ==

* Defining in Playbook:
<pre>
- hosts: all
vars:
user: test
home: /home/test
</pre>
* Using variable files:
<pre>
- hosts: all
vars_files:
- vars/users.yml

$ cat vars/users.yml
user: test
home: /home/test
user: test2
home: /home/test2
</pre>

== Using Variables ==

<pre>
tasks:
- name: Creates the user {{user}}
user:
name: "{{ user }}"
</pre>

== Host and Group Variables ==

Host Variable: Applies to one host defined in Inventory file.
Group Variable: Applies to multiple hosts defined in Inventory file.

* Depricated method: Define them in Inventory file:
[webservers]
webserver.example.com
[webservers:vars]
user=test

* Recommended method: Use group_vars & host_vars directories in project directory which contains inventory file.
nano group_vars/webservers
nano host_vars/server01

* Variables can be overwritten from CLI using
ansible-playbook -e "key=value"

== Arrays ==

* Define multiple values
* Refer to these using: users.test.first_name
users:
test:
first_name: test
last_name: done
home_dir: /home/test
test2:
first_name: test2
last_name: done
home_dir: /home/test2

= Facts =

* Contain discovered information about a host
* Can be used in conditional statements to make sure certain tasks run only if they are necessary.
* Setup module is used to gather fact information
ansible -i inventory servers -m setup

* Facts provide a lot of information, Filter them:
ansible -i inventory servers -m setup -a 'filter=ansible_kernel'

* Custom facts can be created to display information about a host.
* Create a file on the Managed Host:
sudo nano /etc/ansible/facts.d/servers.fact
[server_info]
profile = web_server

Check the facts:
ansible -i inventory servers -m setup -a 'filter=ansible_local'

= Inclusions =

* These make it easy to create a modular Ansible Setup.
* Main variables can be set in the master Ansible file, generic tasks can be defined in included files.
* Tasks can be included in a playbook from external YAML file using '''include''' directive.
* Variables can be included from YAML or JSON file using '''include_vars''' directive.

Latest revision as of 18:43, 19 July 2019

Features of Ansible

  • Ansible is Modular
  • 1000+ Modules available.
  • Modules written in python.

Running Ansible

  • Do not use Root account for ansible
  • Create an account with all privileges:
sudo visudo
%ansible ALL=(ALL)    ALL

usermod -aG ansible aman
  • Install python on all hosts:
yum install -y python2 epel-release
  • Add entry to Hosts file & enable key less SSH access:
ssh-copy-id -i ~/.ssh/id_rsa.pub aman@server2
  • Using the same username is convenient but not required.

Inventory file

cd install
nano inventory
[all]
controller.example.com
node1.example.com
[servers]
node1.example.com
server1.example.com
ansible all -i inventory --list-hosts

Ansible Config File

  • Variour ansible.cfg files:
/etc/ansible/ansible.cfg
~/.ansible.cfg
ansible.cfg in project directory (takes precedence)
  • Contents:
become:           Specify how to escalate privileges on the managed host.
become_user:      Specify which user account to use on remote host.
become_ask_pass:  Whether or not a password should be asked.
inventory:        Which Inventory files to be used.
remote_user:      Name of user account on the managed host. Not set by default, so local username is used.
  • Privilege Escalation
Ansible runs tasks on managed host using same user account as local user, so make sure to copy ssh keys.
Set remote_user in ansible.cfg to specify another user to be used.
If remote_user is not specified, Privilege Escalation can be used.
Enable in [privilege_escalation] section in ansible.cfg:
  become=True
  become_method=sudo
  become_user=root
  become_ask_pass=False
Privilege escalation needs sudo configuration
Create a sudo file on all Ansible managed hosts:
  nano /etc/sudoers.d/user
  user ALL=(ALL) NOPASSWD: ALL

Adhoc Commands

  • Used for Diagnostics like querying a large number of hosts.
  • To quickly make changes to many managed hosts
  • Modules are used:
-m    Specifies Modules 
-a    Specifies Arguments
  • Default Module can be set in ansible.cfg file.
  • 3 Adhoc commands:
command:  runs command on managed host
shell:    runs command on managed host through the local shell
copy:     copy a file, change content on a remote host in a target file
ansible all -i inventory -m command -a id
ansible all -i inventory -m command -a id -o
ansible all -i inventory -m command -a env
ansible all -i inventory -m shell -a env
ansible server1 -m copy -a 'content="Ansible Managed\n" dest=/etc/motd'

Modules

List Modules:

ansible-doc -l

Module Help:

ansible-doc <modulesname>

Create sample config:

ansible-doc -s <modulesname>

Using Modules:

ansible all -i inventory -m ping
ansible -i inventory -m ping all

Using in Playbooks:

tasks:
- name: Install a package
  yum: 
     name: vsftpd
     state: latest

YAML

  • YAML(YAML Ain't Markup Language) structures are represented by indentation.
  • Data elements at same hierarchy level should be at same indentation level.
  • Do not use Tabs for indentation.
  • It is common but not mandatory to start YAML file with 3 dashes & end it with 3 dots.
  • This allows YAML code to be placed in some other code.
  • Example:
---
# example playbook
item1:
  parameter1
  parameter2
    option1
    option2
item2
  parameter3
...

YAML Contents

  • Dictionary: key/value pair written in key: value notation
  • Lists: represent a list of items, enumerated as - item. Space after - is mandatory.
  • Strings can be enclosed in single or double quotes but that is not mandatory.
  • In a multi-line string, first line is ended by | or >. Next lines are indented.
  • Verify YAML syntax:
ansible-playbook --syntax-check mycode.yaml
  • Dry Run:
ansible-playbook -C mycode.yaml
  • Step-by-Step:
ansible-playbook --step mycode.yaml

Playbook

  • Tasks are performed by Modules.
  • Ordering is important: Plays & Tasks are executed in the order they are presented.
  • Playbooks do not change anything if the host is already in desired state.
  • Avoid modules like command, shell & raw as they are not idempotent by nature.

Task Attribute

  • Most important Attribute is Task attribute:
tasks:
- name: run service
  service: name=vsftpd enabled=true
  • Here '-' marks beginning of a list of attributes.
  • If multiple tasks are defined, each first attribute of task starts with '-'.

Other Attributes

name:  specify a specific label to play
hosts: uses patterns to define on which hosts to run a play
remote_user: overwrites the remote_user setting in ansible.cfg
become: overwrites the become setting in ansible.cfg
become_method: overwrites the become_method setting in ansible.cfg
become_user: overwrites the become_user setting in ansible.cfg

Variables

  • Used for repeated tasks like:
Creating users
Removing files
Installing packages
  • Names must start with letters
  • Can be defined at a lot of levels
  • Can be defined with different scope:
Global Scope: Set from CLI or ansible configuration file
Play Scope: Defined in playbook
Host Scope: Set on groups or Individual hosts through inventory file.
  • Variables defined at highest level wins: Global scope wins from host scope

Defining Variables

  • Defining in Playbook:
- hosts: all
  vars:
    user: test
    home: /home/test
  • Using variable files:
- hosts: all
  vars_files:
    - vars/users.yml

$ cat vars/users.yml
user: test
home: /home/test
user: test2
home: /home/test2

Using Variables

tasks:
  - name: Creates the user {{user}}
    user:
      name: "{{ user }}"

Host and Group Variables

Host Variable:  Applies to one host defined in Inventory file.
Group Variable: Applies to multiple hosts defined in Inventory file.
  • Depricated method: Define them in Inventory file:
[webservers]
webserver.example.com
[webservers:vars]
user=test
  • Recommended method: Use group_vars & host_vars directories in project directory which contains inventory file.
nano group_vars/webservers
nano host_vars/server01
  • Variables can be overwritten from CLI using
ansible-playbook -e "key=value"

Arrays

  • Define multiple values
  • Refer to these using: users.test.first_name

users:

 test:
   first_name: test
   last_name: done
   home_dir: /home/test
 test2:
   first_name: test2
   last_name: done
   home_dir: /home/test2

Facts

  • Contain discovered information about a host
  • Can be used in conditional statements to make sure certain tasks run only if they are necessary.
  • Setup module is used to gather fact information
ansible -i inventory servers -m setup
  • Facts provide a lot of information, Filter them:
ansible -i inventory servers -m setup -a 'filter=ansible_kernel'
  • Custom facts can be created to display information about a host.
  • Create a file on the Managed Host:
sudo nano /etc/ansible/facts.d/servers.fact
 [server_info]
 profile = web_server

Check the facts:

 ansible -i inventory servers -m setup -a 'filter=ansible_local'

Inclusions

  • These make it easy to create a modular Ansible Setup.
  • Main variables can be set in the master Ansible file, generic tasks can be defined in included files.
  • Tasks can be included in a playbook from external YAML file using include directive.
  • Variables can be included from YAML or JSON file using include_vars directive.