---
# System prepended metadata

title: Ansible

---

# Ansible
## Vault
1. View vault encrypted file
```bash
$ ansible-vault view foo.yaml
```
## Modules
1. wait_for

Pre-requirements
1. ansible.cfg
remote_user
host key checking
inventory
private key file

2. hosts
[db]
db1.com
db2.com

[db:vars]
variable=value

3. ad-hoc commands
`$ ansible -m ping host/group`
specify user
`$ ansible -m ping host/group --become --become-user=user`

`$ ansible -m yum -a "name=httpd state=latest" host/group`

** **Man page for ansible modules**
`$ ansible-doc module-name`
Example:
`$ ansible-doc yum`

**Playbooks**
Basic format
```
hosts: host/group
gather_facts: True
tasks:
  - name: Install apache
    yum:
      name: httpd
      state: installed
```
Additional parameters in playbooks
loops

```bash=
# To troubleshoot and get more log info enable ldap debug logging in grafana.ini
#[log]
#filters = ldap:debug

[[servers]]
# Ldap server host (specify multiple hosts space separated)
#host = "ad-amer-pdx.xpo.com"
host = "10.53.51.167"
# Default port is 389 or 636 if use_ssl = true
#port = 389
port = 636
# Set to true if ldap server supports TLS
use_ssl = true
# Set to true if connect ldap server with STARTTLS pattern (create connection in insecure, then upgrade to secure connection with TLS)
start_tls = false
# set to true if you want to skip ssl cert validation
ssl_skip_verify = true
# set to the path to your root CA certificate or leave unset to use system defaults
# root_ca_cert = "/path/to/certificate.crt"
# Authentication against LDAP servers requiring client certificates
# client_cert = "/path/to/client.crt"
# client_key = "/path/to/client.key"

# Search user bind dn
bind_dn = "CN=svcGrafana,OU=Service Accounts,OU=IT Infrastructure,DC=amer,DC=corp,DC=xpo,DC=com"
# bind_dn = "cn=admin,dc=grafana,dc=org"

# Search user bind password
# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
#bind_password = 'grafana'
bind_password = '!yFeE4J4H7T9R?JG'

# User search filter, for example "(cn=%s)" or "(sAMAccountName=%s)" or "(uid=%s)"
#search_filter = "(cn=%s)"
search_filter = "(sAMAccountName=%s)"

# An array of base dns to search through
search_base_dns = ["DC=amer,DC=corp,DC=xpo,DC=com"]
#search_base_dns = ["dc=grafana,dc=org"]

## For Posix or LDAP setups that does not support member_of attribute you can define the below settings
## Please check grafana LDAP docs for examples
# group_search_filter = "(&(objectClass=posixGroup)(memberUid=%s))"
# group_search_base_dns = ["ou=groups,dc=grafana,dc=org"]
# group_search_filter_user_attribute = "uid"

# Specify names of the ldap attributes your ldap uses
[servers.attributes]
name = "givenName"
surname = "sn"
username = "sAMAccountName"
member_of = "memberOf"
email =  "mail"

# Map ldap groups to grafana org roles
[[servers.group_mappings]]
group_dn = "CN=GlobalDevOPS_PROD,OU=Groups,OU=IT Infrastructure,DC=amer,DC=corp,DC=xpo,DC=com"
org_role = "Admin"
# To make user an instance admin  (Grafana Admin) uncomment line below
grafana_admin = true
# The Grafana organization database id, optional, if left out the default org (id 1) will be used
# org_id = 1

[[servers.group_mappings]]
group_dn = "cn=users,dc=grafana,dc=org"
org_role = "Editor"

[[servers.group_mappings]]
# If you want to match all (or no ldap groups) then you can use wildcard
group_dn = "*"
org_role = "Viewer"

```
Configuration for sudo, asking for password
```bash=
[defaults]
inventory = ./inventory

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = true
```

## Ansible commands
1. To list all the hosts in inventory
```bash=
ansible all --list-hosts
```
2. To list all the hosts for a specific group in inventory
```bash=
ansible webservers --list-hosts
```
3. Run play only for a specific group
```bash=
when: inventory_hostname in groups['masters']
```
```bash
# Define SSH user
ansible-playbook -e ansible_user=ec2-user playbook.yaml
# Define PEM key 
ansible-playbook -e ansible_ssh_private_key_file=/root/key.pem playbook.yaml
```
## Facts
* Ansible facts are variables that are automatically discovered by Ansible on a managed host. 
* Facts contain host-specific information that can be used just like regular variables in plays.
* Examples like hostname, IP address, distro, number of CPU, free memory etc
* **setup** module is used to collect facts.

## variables
```bash=
cat vars.yml
packages:
  - httpd
  - vim
  - nginx

config_files:
  - src: foo
    dest: bar
  - src: foo2
    dest: bar2
# when referrring, use "{{ config_files.src }} and  "{{ config_files.dest}}"
```

## Terms
* privileged escalation
* remote_user
* facts
* ansible vault - vault id, ask vault passwd
* ansible facts - custom facts
* block
    * rescue
    * always
* deletegate_to
* register
* notify
* handler
* changed_when: false (system date)
* failed_when: web_package == "httpd"
* vars_files
* inventory_name
* force_handlers: yes <-- use this, becoz handler will be notified only if there is a change. 
* when
## Scenarios
1. Run shell script
```yaml=
tasks:
     - name: Transfer executable script script
       copy: src=/opt/ashah/crunchify-script.sh dest=/opt/ashah mode=0777
     - name: Execute the script
       command: sh /opt/ashah/crunchify-script.sh
```
## Questions
1. How do you dynamically configure MySQL configuration based on the available memory on the target hosts?
Use **ansible facts** to discover available memory and configure them accordigly.
2. How do you print outout of a command?