Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates. Ansible manages machines in an agent-less manner. There is never a question of how to upgrade remote daemons or the problem of not being able to manage systems because daemons are uninstalled.
Installing Ansible
Install Pre-requisites
- Ubuntu Linux environment 14.04+
- Setup SSH keys
Install Steps
While the Ubuntu default repository includes an Ansible package, it is very far behind the upstream project in versioning. Recommend to use the version from the ppa. Instructions taken from http://docs.ansible.com/ansible/intro_installation.html#latest-releases-via-apt-ubuntu.
-
sudo apt-get install software-properties-common
-
sudo apt-add-repository ppa:ansible/ansible
-
sudo apt-get update
-
sudo apt-get install ansible
Verify that the installed version is > 2.1 via: ansible –version
Configure Ansible Playbooks
Ansible Playbooks run the configurations against the hosts.
1. Set save credentials:
export TF_AUTO_SAVE_CREDENTIALS=1 |
2. Test: run an Ansible Playbook as a test:
# add host to your ssh known_hosts ssh server-name-01 # # note the setup: # 1. Playbook.yml, 2. -i (inventory), 3. pass common vars, including password vault, 4. pass extra vars, including hostname and environment, 5. unlock the password vault # ansible-playbook configure-apt.yml -i " -e @common_vars /common_vars .yml --extra-vars 'env=local variable_host= - v -C --vault-password- file ~ /vars/ .common.txt |
- Optional: Test by running an Ansible command
- Ansible role-name –ssh-extra-args=”-o PubKeyAuthentication=no -o StrictHostKeyChecking=no” -m ping -k
- Optional: Deploy your public ssh key to an Ansible host to test
- Recommend getting someone who already has keys deployed to run the recipe the first time
- Otherwise, you’ll need to connect as a sudo account using password
- In the ansible-playbook command, disable PubKeyAuthentication and StrictHostKeyChecking if running manually as a specific remote_user
- –ssh-extra-args=”-o PubKeyAuthentication=no -o StrictHostKeyChecking=no”
Further Configuration
While Ansible will work via ssh and prompting for passwords, it is better practice to use ssh keys for authentication. Use a playbook to push SSH keys out to hosts.
Create Ansible Playbook
The following are various examples to refer to when building an Ansible Playbook:
Playbook
Ansible Playbooks require a name, hosts lists the inventory, roles begin a set of tasks.
Hosts
Run a specific task against a set of hosts, called a host inventory (note the default):
--- - name: Test Playbook to run a shell command hosts: "{{ variable_host | default('host-group-name')}}" become: yes tasks: - name: run this command and ignore the result shell: /usr/bin/somecommand ignore_errors: True ... |
Pass the host list as a variable:
hosts: "{{ variable_host | default('web')}}" # command ansible-playbook server.yml --extra-vars "variable_host=server-name-01" |
Roles
Use roles instead of tasks:
--- - name: Test Playbook to run a role hosts: host-group-name become: yes roles: - role-name-of-role ... |
Output Debug Message
- debug: msg: "Host: {{ variable_host }} has a message to output." |
Hosts
Use a host variable, or use a host inventory:
Host Variable
hosts: "{{ variable_host | default('web')}}" # command ansible-playbook server.yml --extra-vars "variable_host=server-name-01" |
Host Inventory
/ansible-playbooks/ansible_inventory
Lists a host group and list of hosts.
[host-group-name]
|
Group Vars
/group_vars/name-of-group.yml
--- env : dev variable-name-01: "/path/to/somewhere" variable-name-02: "some variable" variable-name-03: "user name 01" ... |
Roles
Roles in Ansible build on the idea of include files and combine them to form clean, reusable abstractions. Roles allow you to focus more on the big picture and only dive down into the details when needed.
Within a role:
Files
For example: /roles/role-name/files/dev/file.keytab
Any copy, script, template or include tasks (in the role) can reference files in roles without having to path them relatively or absolutely.
Tasks
For example: /roles/dsiq-product-dictionary/tasks/main.yml
--- - name: setup-file-keytab- dir file : path: "{{ owner: "{{ group: "{{ mode: 0770 state: directory - name: copy-file-keytab- copy: dest: "{{ src: "{{ env }}/" owner: "{{ group: "{{ mode: 0770 ... |
Run a Command within a Task
You may find it necessary to run a command on the command-line within a task.
--- # playbook to restart a service - name: restart-service hosts: "{{ variable_host }}" become: yes user: root tasks: - name: stop-start- if -service command : bash -c "ifdown eth0 && ifup eth0" ... |
Defaults
Example: /roles/role-name/defaults/main.yml
To create defaults, simply add a defaults/main.yml file in your role directory. These variables will have the lowest priority of any variables available, and can be easily overridden by any other variable, including inventory variables.
--- env : dev variable-name-01: "/another/path/to/somewhere" variable-name-02: "another variable" variable-name-03: "override user name 01" ... |
Example Commands
Command Line
Generic Ansible Command (automation script)
# browse to your list of playbooks cd /dir/ ` whoami ` /to/ansible-playbooks # # run playbook with validation flag to test host, authentication, and the validity of the playbook itself. Include env and host vars ansible-playbook configure-apt.yml -i "server-name-01," -e @common_vars /common_vars .yml --extra-vars 'env=local variable_host=server-name-01' - v --vault-password- file ~ /vars/ .common.txt |
Add hostname to known_hosts
Useful for running against a large set of hosts as the playbooks will not be broken apart by the question to add the host to the known_hosts file. Simply call this from your playbook:
ansible-playbook -i "server-name-01," dsiq- ssh -keyscan.yml - v |
Run a command against a host list
Using -l to indicate host list:
ansible-playbook configure- ssh -keys.yml -l host-names --list-hosts ansible-playbook configure-dev.yml -l additional-hosts --list-hosts -C |
Run a playbook against a host pass encrypted credentials on the command-line using the password vault
Using -i to indicate inventory (and host vars to pass the host name to the playbook):
ansible-playbook configure-apt.yml -i "server-name-01," -e @common_vars /common_vars .yml --extra-vars 'env=local variable_host=server-name-01' - v -C --vault-password- file ~ /vars/ .common.txt |
Run a command against an inventory
Create a directory, set permissions on the directory, and copy a file:
cd /dir/to/ansible-playbooks/ # apply to the hosts-dev group ansible hosts-dev-a "sudo mkdir -p /dir/name/ owner=root group=root" - v ansible hosts-dev -a "sudo chmod -R 777 /dir/name/" - v ansible hosts-dev -a "sudo chown -R root:root /dir/name/" - v ansible hosts-dev -m copy -a "src=~/from/dir/name/file.keytab dest=/dir/name/ mode=700 owner=root group=root" - v ansible hosts-dev -a "sudo chmod -R 700 /dir/name/" - v |
Run a command against a single server
There’s a cute little trick that lets you specify a single host on the command line (or multiple hosts, I guess), without an intermediary inventory:
ansible "server-name-01," -a "sudo chmod -R 770 /dir/name/" - v --list-hosts |
Note the comma (,) at the end; this signals that it’s a list, not a file.
Run multiple Shell commands
ansible "erver-name-01," -m shell -a 'sudo mkdir -p /dir/name/;sudo chmod -R 777 /dir/name/;' - v |
Run command using the automation account
If you don’t have permissions to access a server, chances are the automation account does…
The automation account is used to script ansible commands. The account uses an encrypted password when run as a script and allows ansible access to all servers.
Use the –ask-vault-pass to inject the account – the password will be asked for on the command line
ansible hosts-list -a "sudo mkdir -p /dir/name/" - v --ask-vault-pass |
Passing Variables On The Command Line
In addition to vars_prompt and vars_files, it is possible to send variables over the Ansible command line. This is particularly useful when writing a generic release playbook where you may want to pass in the version of the application to deploy:
ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo" |
This is useful, for, among other things, setting the hosts group or the user for the playbook.
Example:
—
– hosts: ‘{{ hosts }}’
remote_user: ‘{{ user }}’
tasks:
–
…
ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck" |