92
Getting Started with Ansible Andrew Hamilton

Getting Started with Ansible

Embed Size (px)

Citation preview

Getting Started with Ansible

Andrew Hamilton

Who Am I?Ops at Prevoty

Former SRE @Twitter and Sys Adm at Eucalyptus

What We’ll DiscussWhy Ansible?

The basics of Ansible

Moving past the basics

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.

http://docs.ansible.com/

One Tool, Multiple Jobs

One Tool, Multiple JobsAd-hoc commands

Configuration Management

Deployments

Agentless

Agentless

Cloud native

Great for ad-hoc commands

SSH based

Idempotent

IdempotentWell mostly…

Allows you to run most modules multiple times without fear

Extensible

ExtensibleLarge community

Lots of prebuilt modules (100s)

Easy to build custom modules

Modules are “Polygot”

Simple

SimpleSyntax based on YAML

Quick and easy setup

Tasks are executed in the order written

It isn’t eventually convergent

1. Setup nginx repo

2. Install nginx

3. Configure vhost

4. Copy over the site files

2. Install nginx

1. Setup nginx repo

4. Copy over the site files

3. Configure vhost

2. Install nginx

1. Setup nginx repo

4. Copy over the site files

3. Configure nginx

2. Install nginx

1. Setup nginx repo

4. Copy over the site files

3. Configure nginx

2. Install nginx

1. Setup nginx repo

4. Copy over the site files

3. Configure nginx

Installation

Installation: Packages$ pip install ansible

# yum install ansible

# aptitude install ansible

$ brew install ansible

Installation: Source$ git clone \ > https://github.com/ansible/ansible

$ source ansible/hacking/env-setup

Inventory

InventoryA list of systems built into groups

Either static or dynamic

Inventory: Static[my_hosts]host1.example.comhost2.example.com

[webservers]www1.example.comwww2.example.com

[dbs]db1.example.comdb2.example.com

Inventory: DynamicBuilds a JSON inventory of hosts

Provided: AWS, GCE, Azure, OpenStack, VMWare, Rackspace, Linode, Digital Ocean, Cobbler, Vagrant, Fleet, Consul, ...

Run an ad-hoc task

Run an ad-hoc task

$ ansible -i <inventory> \> -m <module> \> -a <args> \> <hosts_identifier>

Run an ad-hoc task$ ansible -i my_inventory \> -m ping \> all

But what if I want to run a command often or multiple commands?

Playbooks

---- hosts: tag_service_web_server

vars:- local_dir: “/myapp”- dest_dir: “/var/www”

tasks:- name: Install nginx

yum: name=nginx.x86_64 state=present

- name: Start nginxservice: name=nginx state=started

- name: Copy over the appcopy: src={{ local_dir }} dest={{ dest_dir }}

recursive=yes owner=nginx mode=0644directory_mode=yes

ansible-playbook -i <inventory> <playbook>

Hosts

---- hosts: tag_service_web_server

vars:- local_dir: “/myapp”- dest_dir: “/var/www”

tasks:- name: Install nginx

yum: name=nginx.x86_64 state=present

- name: Start nginxservice: name=nginx state=started

- name: Copy over the appcopy: src={{ local_dir }} dest={{ dest_dir }}

recursive=yes owner=nginx mode=0644directory_mode=yes

HostsAllows you to specify groups of hosts

Uses the provided inventory

Vars

---- hosts: tag_service_web_server

vars:- local_dir: “/myapp”- dest_dir: “/var/www”

tasks:- name: Install nginx

yum: name=nginx.x86_64 state=present

- name: Start nginxservice: name=nginx state=started

- name: Copy over the appcopy: src={{ local_dir }} dest={{ dest_dir }}

recursive=yes owner=nginx mode=0644directory_mode=yes

VarsAllows you to dynamically change values

Can be used in playbooks and templates

Different types of variables for different workloads

Vars: RuntimeYou can add variables from the CLI at runtime

Runtime variables take precedence

$ ansible-playbook -i <inventory> \> -e key1=value1 playbook.yml

3 types of varsStandard:

my_str: “my string”my_num: 1my_float: 1.234923409my_bool: false*

* booleans also allow “yes” and “no”

3 types of varsLists:

a_list: [‘one’, ‘two’, ‘three’]another: [1, 2, 3]

3 types of varsHashes (Dictionaries):

a_hash: { “key”: “value”, }hashing_it_up: { “such”: “wow”,

“chosen”: 1, }

3 types of varsCombining them together

my_var: “Here”complex: [

{ “key”: “value”, },{ “key”: “blah”, },{ “key”: my_var },

]

Jinja templating for varsUse “{{ <var> }}” to access variables

{{ my_var }}{{ my_list[0] }}{{ my_hash[“key”] }}

Tasks

---- hosts: tag_service_web_server

vars:- local_dir: “/myapp”- dest_dir: “/var/www”

tasks:- name: Install nginx

yum: name=nginx.x86_64 state=present

- name: Start nginxservice: name=nginx state=started

- name: Copy over the appcopy: src={{ local_dir }} dest={{ dest_dir }}

recursive=yes owner=nginx mode=0644directory_mode=yes

TasksUses modules to complete tasks

100s of prebuilt modules

Examples: template, copy, yum, apt, pip, ec2, elb, docker

Can use custom modules in tasks too

TasksRequired:

- <module_name>: <key1>=<value1> <key2>=<value2> …

TasksOptional:

name, become, become_user, connection, delegate_to, etc

TasksExample:

- name: Install nginxbecome: yesyum: name=nginx state=latest

Questions?

http://www.slideshare.net/ahamilton55

Loops

LoopsAllows for cycling through items in a task

with_items, with_nested, with_dict, etc

Loopswith_items:- <item1>- <item2>- <item3>

Loops- name: Install nginx

yum: name=nginx.x86_64 state=latest

- name: Install php5yum: name=php5.x86_64 state=latest

- name: Install Laravelyum: name=php5-laravel.x86_64 state=latest

Loops- name: Install packages

yum: name={{ item }} state=latestwith_items:- nginx.x86_64- php5.x86_64- php5-laravel.x86_64

Loops- name: Install packages

yum: name={{ item.name }} state={{ item.ver }}with_items:- { “name”: ”nginx.x86_64”, “ver”: ”latest” }- { “name”: ”php5.x86_64”, “ver”: ”5.4-1” }- { “name”: ”php5-laravel.x86_64”, ver”: ”5.4-123-1” }

Conditionals

ConditionalsAllows you to run tasks only when constraints are met

when

Conditionalswhen: <some boolean logic>

Conditionals- name: Install nginx

yum: name=nginx.x86_64 state=latest

But what if we want to also use a Deb based distro?

Conditionals- name: Install nginx (RH)

yum: name=nginx.x86_64 state=latestwhen: ansible_os_family == “RedHat”

- name: Install nginx (Deb)apt: name=nginx state=latestwhen: ansible_os_family == “Debian”

Variables Files

Variables FilesJust files full of variables…

Makes using a large number of variables easier

Cleans up your playbooks

Variables FilesMultiple level:- Site- Group- Host

Variables FilesSite / Groups:

Best practice to place in a group_vars dir

group_vars/all for site varsgroup_vars/<group_name> for groups

Variables FilesHosts:

Best practice to place in a host_vars dir

host_vars/<hostname>

Variables Files: webserverindex_page: index.htmldomains: [

‘example.com’,‘www.example.com’

]server_names: “{{ domains|join(‘ ‘) }}”vhost_root_dir: “/usr/local/www/{{ domains[0] }}/htdocs”

Variables Files- hosts: webservers

vars_files:- group_vars/all- group_vars/webserverstasks:- name: Install nginx

yum: name=nginx state=latest

Roles

RolesUsed as a way to organize playbooks

Allows for portability and reuse

RolesDownload roles from the community at

https://galaxy.ansible.com/

Use ansible-galaxy CLI too

Roles<role_name>/

files/templates/tasks/handlers/vars/defaults/meta/

RolesCreate this directory structure easily

$ ansible-galaxy init <role_name>

RolesBy default the main.yml file will be run

Can create multiple playbooks in a role

Roles: webserver.ymlhosts: webserversvars_files:- group_vars/all- group_vars/webserversroles:- nginx

Rolesnginx/ templates/

nginx.conftasks/

main.ymlredhat.ymldebian.yml

handlers/main.yml

Roles: templates/nginx.confhttp { index {{ index_page }}; server { server_name {{ server_names }}; access_log logs/{{ main_domain }}.access.log main; root {{ vhost_root_dir }}; }}

Roles: tasks/redhat.yml---- name: Install nginx

yum: name=nginx state=latestnotify:- start nginx- enable nginx

Roles: tasks/debian.yml---- name: Install nginx

apt: name=nginx state=latestnotify:- start nginx- enable nginx

Roles: tasks/main.yml---- include: redhat.yml

when: ansible_os_family == “RedHat”

- include: debian.ymlwhen: ansible_os_family == “Debian"

- name: Copy over the nginx.conf templatetemplate: src=nginx.conf dest=/etc/nginx/nginx.confnotify: restart nginx

Roles: handlers/main.yml---- include: redhat.yml

when: ansible_os_family == “RedHat”

- include: debian.ymlwhen: ansible_os_family == “Debian”

- name: start nginxservice: name=nginx state=started

- name: restart nginxservice: name=nginx state=restarted

Roles: handlers/redhat.yml---- name: enable nginx

service: name=nginx enabled=yes

Roles: handlers/debian.yml---- name: enable nginx

command: update-rc.d nginx enable

Secrets

Secrets$ANSIBLE_VAULT;1.1;AES256343836626534373165643662656363373866626639396535393063336336333162643832353466386631366536656336353137363462643435376164363339360a303264343761336135386564653138393264613961656430666639383339653465303330613333366330366131383033353761643463623161373230353036640a6439613064666466393861633034613534613966653933353837316532663964646435343837323865613061313137346535343239653334376364323932316238386161303764343665346666333231333461636634353061313332613934313433343834366434623866636366313936656463363832343130643139636535363432333861313430343033376566613764623161616565376466383833306164386532656662306437333464343139376362613933653964643536343265623438346634616462313965643038366265646264636538636238306330306430343439633165323330323539616165333039356261613332393332376633636436656636613639613438663335316532643536326264646536636536623061383661656534633130663534316162646236636631323866336530393562636565636166646637616465313037396339633264643731366436623030326633393934346437636663636563333832303165633637303065343732323539643834643066613734363366643933613533343631303930623765616238323633393638333733663835616637306635666466636633323437343665646433383637623932316139363639323565663230656432363731623230

SecretsBuiltin support for using AES256 encrypted variables files

Files kept in group_vars files for easy access

Pass in password at execution

Secretsansible-vault CLI tool

Easy to edit, view, encrypt, decrypt, create and rekey files

Secretsansible-playbook --ask-vault-pass …

ansible-playbook --vault-password-file ...

Also, I’m hiring

[email protected]