From charlesreid1

 
(11 intermediate revisions by the same user not shown)
Line 1: Line 1:
=Example: Secure Nginx Server=
=Overview=


[[Ansible/Nginx_Playbook]] - a page that walks through two example playbooks
The Ansible documentation has a nice overview of playbooks: https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html


* [https://charlesreid1.com/wiki/Ansible/Nginx_Playbook#Ansible_Playbook_Example_1:_Nginx_Server_Playbook Example 1: nginx server playbook]
==Brief Notes==
* [https://charlesreid1.com/wiki/Ansible/Nginx_Playbook#Ansible_Playbook_Example_2:_Secure_Nginx_Server_Playbook Example 2: secure nginx server playbook]


This page walks through a procedure resulting in the following files:
===Playbooks===


<pre>
* playbooks are a way of executing commands on remote machines in a scripted way
    playbooks/ansible.cfg
* can orchestrate multiple ordered processes
    playbooks/hosts
* playbooks are written in YAML
    playbooks/Vagrantfile
* each playbook can contain one or more plays
    playbooks/web-notls.yml
* each play will target different servers (maybe all of them, maybe just web servers, maybe just db servers)
    playbooks/web-tls.yml
* user specifies hosts - remote machines on which Ansible will run commands
    playbooks/files/nginx.key
* users - the remote user is the user that Ansible will run the particular task as
    playbooks/files/nginx.crt
    playbooks/files/nginx.conf
    playbooks/templates/index.html.j2
    playbooks/templates/nginx.conf.j2
</pre>


==Before you begin: Vagrant configuration==
===Tasks===
 
This assumes we will be setting up a Ubuntu machine using Vagrant. (See [[Vagrant]] page for steps.)


Before starting, we want to remap some ports.
* each play has a list of tasks associated with it
* tasks are executed in order on all machines that match the host pattern
* ansible completes the task on all remote machines before it moves on to the next task


We want to arrange the Vagrant machine so that we map the local port 8080 to the vagrant machine's port 80, and map the local port 8443 to the vagrant machine's port 443.
===Handlers===


The Vagrantfile is a Ruby file that specifies how to start up and set up the Vagrant boxes. The Vagrantfile should be modified as follows:
* handlers are "conditional tasks" - tasks that are triggered by other tasks
* the handlers are triggered once at the end of each block of tasks - this keeps them from being restarted over and over by a set of related tasks


<pre>
===Roles===
VAGRANTFILE_API_VERSION = "2"


Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
* Roles are just a way of automatically loading variables, tasks, and task handlers.
  config.vm.box = "ubuntu/xenial64"
* Roles use a known file structure to load appropriate vars/tasks/handlers
  config.vm.network "forwarded_port", guest: 80, host: 8080
* A given play will specify a list of roles in the playbook - this indicates that ansible should look for variables/tasks/handlers that match up with those roles, and add them to the play
  config.vm.network "forwarded_port", guest: 443, host: 8443
* Roles can be dependent on other roles (that's the purpose of the "meta" yaml file)
end
</pre>


Now instruct vagrant to reload from the Vagrantfile:
Example:
* the following playbook entry will automatically populate the play with a list of variables, tasks, and handlers from the roles subdirectory
* the roles subdirectory will contain two subdirectories, common and web, with files for those roles


<pre>
<pre>
$ vagrant reload
---
 
# playbook.yml
==> default: Forwarding ports...
- name: example play
    default: 80 => 8080 (adapter 1)
    default: 443 => 8443 (adapter 1)
    default: 22 => 2222 (adapter 1)
</pre>
 
==Creating a simple playbook==
 
The following simple playbook will set up an nginx web server on our fresh Ubuntu machine.
 
===The Pieces===
 
Here are the pieces in our playbook:
 
* The playbook itself (YAML file)
* nginx configuration file
* nginx HTML templates
* Create Ansible group webservers
 
===The Playbook: YAML file===
 
Here is a simple playbook for our secure nginx server:
 
'''<code>web-notls.yml</code>:'''
 
<pre>
- name: Configure webserver with nginx
   hosts: webservers
   hosts: webservers
   become: True
   roles:
  tasks:
  - common
    - name: install nginx
  - web
      apt: name=nginx update_cache=yes
 
    - name: copy nginx config file
      copy: src=files/nginx.conf dest=/etc/nginx/sites-available/default
 
    - name: enable configuration
      file: >
        dest=/etc/nginx/sites-enabled/default
        src=/etc/nginx/sites-available/default
        state=link
 
    - name: copy index.html
      template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html
        mode=0644
 
    - name: restart nginx
      service: name=nginx state=restarted
</pre>
</pre>


Required files: <code>/etc/nginx/sites-available/default</code>, <code>/usr/share/nginx/html/index.html</code>
===Tags===


YAML truth-y values: <code>true, True, TRUE, yes, Yes, YES, on, On, ON, y, Y</code>
* Tags are a way of only running part of your playbook
* Think of tags as a filtering operation


YAML false-y values: <code>false, False, FALSE, no, No, NO, off, Off, OFF, n, N</code>
===Idempotence===


===nginx config file===
* idempotent means you can run it multiple times with the same outcome as running it one time
* modules should check whether the desired final state has already been achieved, and exit without doing anything if so


Here is the corresponding nginx configuration file, which we put in <code>files/nginx.conf</code>:
=Example: Secure Nginx Server=


'''files/nginx.conf:'''
[[Ansible/Nginx Playbook]] - a page that walks through two example playbooks


<pre>
* [https://charlesreid1.com/wiki/Ansible/Nginx_Playbook#Ansible_Playbook_Example_1:_Nginx_Server_Playbook Example 1: nginx server playbook]
server {
* [https://charlesreid1.com/wiki/Ansible/Nginx_Playbook#Ansible_Playbook_Example_2:_Secure_Nginx_Server_Playbook Example 2: secure nginx server playbook]
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;


        root /usr/share/nginx/html;
=Full Stack Example: Django Celery RabbitMQ Postgres=
        index index.html index.htm;


        server_name localhost;
[[Ansible/Full Stack Playbook]] - a page that walks through a playbook for a full stack example


        location / {
=Flags=
                try_files $uri $uri/ =404;
        }
}
</pre>
 
===nginx index html page===
 
Likewise, we want to create an index page for nginx to serve up, and we want to put template files into the playbook directory, in the templates subdirectory.
 
(NOTE: .j2 extension means it is a Jinja 2 template)
 
'''playbooks/templates/index.html.j2'''
 
<pre>
<html>
  <head>
    <title>Welcome to ansible</title>
  </head>
  <body>
  <h1>nginx, configured by Ansible</h1>
  <p>If you can see this, Ansible successfully installed nginx.</p>
 
  <p>Running on {{ inventory_hostname }}</p>
  </body>
</html>
</pre>
 
===Creating webservers Ansible group===
 
We will create a <code>webservers</code> Ansible group in the inventory file and refer to this group in the Ansible playbook.
 
In the playbooks/hosts file the "myvagrantbox" line is put under the heading <code>[webservers]</code>:
 
'''<code>playbooks/hosts</code>'''
 
<pre>
[webservers]
myvagrantbox ansible_host=127.0.0.1 ansible_port=2222
</pre>
 
Now test it out: ping the webservers group with a single command:
 
<pre>
$ ansible webservers -m ping
</pre>
 
Output:
 
<pre>
testserver | success >> {
    "changed": false,
    "ping": "pong"
}
</pre>
 
==Running a simple playbook==
 
The <code>ansible-playbook</code> command is used to execute playbooks:
 
<pre>
ansible-playbook web-notls.yml
</pre>
 
Alternatively, to run a playbook directly, use the shebang line:
 
<pre>
#!/usr/bin/env ansible-playbook
</pre>


Then execute it directly:
{{AnsibleFlag}}
 
<pre>
./web-notls.yml
</pre>
 
==Anatomy of example playbook==
 
Let's examine the example playbook in detail.
 
===Plays===
 
A playbook is a list of plays.
 
Every play has:
 
* a set of hosts to configure
* a set of tasks to run on those hosts
* the play is the thing that connects hosts to tasks
 
Optional play settings:
 
* name - a comment that describes what the play is about
* become - if true, Ansible will run each task by becoming the root user (useful for Ubuntu, where ssh as root is disabled by default)
* vars - list of variables and values
 
In our example, the play is this entire section:
 
<pre>
- name: Configure webserver with nginx
  hosts: webservers
  become: True
  tasks:
    - name: install nginx
      apt: name=nginx update_cache=yes
 
    - name: copy nginx config file
      copy: src=files/nginx.conf dest=/etc/nginx/sites-available/default
 
    - name: enable configuration
      file: >
        dest=/etc/nginx/sites-enabled/default
        src=/etc/nginx/sites-available/default
        state=link
 
    - name: copy index.html
      template: src=templates/index.html.j2
              dest=/usr/share/nginx/html/index.html mode=0644
 
 
    - name: restart nginx
      service: name=nginx state=restarted
</pre>
 
===Tasks===
 
The tasks are the actions that are performed when the play is run.
 
The first task is to install nginx:
 
<pre>
- name: install nginx
  apt: name=nginx update_cache=yes
</pre>
 
This can also be written without the optional name parameter,
 
<pre>
- apt: name=nginx update_cache=yes
</pre>
 
Can also fold over multiple lines using <code>></code>:
 
<pre>
- name: install nginx
  apt: >
      name=nginx
      update_cache=yes
</pre>
 
Actions in tasks are composed of modules.
 
 
===Modules===
 
There are lots of useful modules that come with Ansible that can be used from playbooks.
 
* apt - installs/removes packages using aptitude package manager
* copy - copies files from local machine to host
* file - sets attributes of files/symlinks/directories
* service - starts/stops/restarts a service
* template - generates a file from a template and copies it to the hosts
 
=Flags=


[[Category:Ansible]]
[[Category:Ansible Playbooks]]
[[Category:Infrastructure]]
[[Category:Python]]

Latest revision as of 17:00, 10 December 2018

Overview

The Ansible documentation has a nice overview of playbooks: https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html

Brief Notes

Playbooks

  • playbooks are a way of executing commands on remote machines in a scripted way
  • can orchestrate multiple ordered processes
  • playbooks are written in YAML
  • each playbook can contain one or more plays
  • each play will target different servers (maybe all of them, maybe just web servers, maybe just db servers)
  • user specifies hosts - remote machines on which Ansible will run commands
  • users - the remote user is the user that Ansible will run the particular task as

Tasks

  • each play has a list of tasks associated with it
  • tasks are executed in order on all machines that match the host pattern
  • ansible completes the task on all remote machines before it moves on to the next task

Handlers

  • handlers are "conditional tasks" - tasks that are triggered by other tasks
  • the handlers are triggered once at the end of each block of tasks - this keeps them from being restarted over and over by a set of related tasks

Roles

  • Roles are just a way of automatically loading variables, tasks, and task handlers.
  • Roles use a known file structure to load appropriate vars/tasks/handlers
  • A given play will specify a list of roles in the playbook - this indicates that ansible should look for variables/tasks/handlers that match up with those roles, and add them to the play
  • Roles can be dependent on other roles (that's the purpose of the "meta" yaml file)

Example:

  • the following playbook entry will automatically populate the play with a list of variables, tasks, and handlers from the roles subdirectory
  • the roles subdirectory will contain two subdirectories, common and web, with files for those roles
---
# playbook.yml
- name: example play
  hosts: webservers
  roles:
   - common
   - web

Tags

  • Tags are a way of only running part of your playbook
  • Think of tags as a filtering operation

Idempotence

  • idempotent means you can run it multiple times with the same outcome as running it one time
  • modules should check whether the desired final state has already been achieved, and exit without doing anything if so

Example: Secure Nginx Server

Ansible/Nginx Playbook - a page that walks through two example playbooks

Full Stack Example: Django Celery RabbitMQ Postgres

Ansible/Full Stack Playbook - a page that walks through a playbook for a full stack example

Flags