Tabela de conteúdo [Esconder]
- 1. Instalação do Ansible
- 2. Inventários
- 3. Comandos Ansible
- 4. Tasks
- 5. Playbook
- 6. Suporte a Python3 – Utilização da variável ansible_python_interpreter
- 7. Alguns playbooks – Instalação do Apache, Nginx e Mysql.
- 8. Copia de Arquivos
- 9. Utilização de templates
- 10. Utilização do módulo lineinfile para a configuração de arquivos
- 11. Instalacão do Mysql, Banco e usuário
- 12. Roles
- 13. Includes
- 14. Variáveis – Facts
Começei a estudar o Ansible, segue aí minhas anotações. Qualquer dúvida ou contribuição, mande nos comentários.
1. Instalação do Ansible
Infraestrutura de estudo utilizada neste Lab:
AnsibleControl-01 – Ubuntu 14.04.5 LTS
Onde será instalado o Ansible. Será o servidor de administração do ambiente. O Ansible vai ser instalado apenas neste servidor.
APP-01 – Webserver (Apache ou Nginx) – Ubuntu 14.04.5 LTS
DB-01 – Banco de dados – Ubuntu 14.04.5 LTS
LB-01 – Loadbalancer – Ubuntu 16.04.3 LTS
1.1. Documentação – Página de instalação do Ansible
http://docs.ansible.com/ansible/latest/intro_installation.html
1.2. Instalação do repositório PPA do Ansible, update do repositório e instalação do Ansible
Logado no servidor de controle ansiblecontro-01, execute os passos para instalação do
reposítório e Ansible.
# apt-get install software-properties-common # apt-add-repository ppa:ansible/ansible # apt-get update # apt-get install ansible |
Verifique a versão do Ansible.
# ansible --version # ansible-playbook --version |
2. Inventários
Um inventário no Ansible pode entender-se como uma lista de servidores/hosts que serão genrenciados pelo Ansible.
Por padrão, seu invetário de hosts é definido no arquivo “/etc/ansible/hosts”.
Você pode criar grupos de hosts ou simplesmente criar uma lista de hosts sem qualquer grupo.
Exemplos:
Sem grupos
# cat /etc/ansible/hosts lb-01.devopslab.com.br app-01.devopslab.com.br db-01.devopslab.com.br |
Servidores organizados por grupos.
cat /etc/ansible/hosts [loadbalancer] lb-01.devopslab.com.br [webserver] app-01.devopslab.com.br app-02.devopslab.com.br [database] db-01.devopslab.com.br [ansible] ansiblecontrol-01.devopslab.com.br |
2.1. Listando todos os servidores com o comando “ansible –list-hosts all”
# ansible --list-hosts all hosts (5): db-01.devopslab.com.br app-01.devopslab.com.br app-02.devopslab.com.br ansiblecontrol-01.devopslab.com.br lb-01.devopslab.com.br |
2.2. Tipo de conexão
Ao criar os hosts do invetário, é possível definir o tipo de conexão que o Ansible vai tentar fazer nos hosts.
/etc/ansible/hosts [ansible] ansiblecontrol-01.devopslab.com.br ansible_connection=local |
Veja que nesta forma, o Ansible vai tentar fazer uma conexão local, sem utilizar o padrão ssh.
2.3. Inventário não padrão !hosts
Também é possível criar um inventário de hosts em um arquivo que não seja o padrão
/etc/ansible/hosts
ansible -i servidores-prod --list-hosts all ansible -i servidores-homol --list-hosts all ansible -i servidores-dev --list-hosts all |
No caso, eu criei um arquivo para cada grupo de servidores.
3. Comandos Ansible
Comandos Ansible para diversos usos. Em andamento…
Listagem de hosts:
ansible --list-hosts all ansible --list-hosts "app*" ansible --list-hosts "lb*" |
Listagem de hosts com negação:
ansible --list-hosts \!app* |
3.1 – Checar a sintaxe dos Playbooks .yml
Eu gosto de usar o próprio “vi” para editar os arquivos .yml, porém as vezes passa alguns erros despercebidos.
ansible-playbook playbooks/install-httpd.yml --syntax-check |
4. Tasks
Execução de comandos/tarefas.
”
-m MODULE_NAME, –module-name=MODULE_NAME
module name to execute (default=command)
”
Execução em todos os hosts listados em “/etc/ansible/hosts”
# ansible -m ping all # ansible -m command -a "hostname" all |
Execução em um único host.
# ansible -a "echo hello" app-01.devopslab.com.br |
DOC com vários módulos suportados pelo Ansible:
https://docs.ansible.com/ansible/devel/modules/list_of_commands_modules.html
5. Playbook
O lance do Playbook do Ansible, é você escrever todas as tarefas que você precisa executar em um arquivo YAML, ou seja, são nos playbooks que você vai organizar a automação.
Alguns Playbooks simples.
Crie uma pasta para armazenar seus Playsbooks.
/etc/ansible/playbooks |
1.
HOSTNAME
/etc/ansible/playbooks/hostname.yml
1
2
3
4
|
--- - hosts: all tasks: - command: hostname |
DATE
/etc/ansible/playbooks/date.yml
1
2
3
4
|
--- - hosts: all tasks: - command: date |
execução do playbook
ansible-playbook hostname.yml ansible-playbook date.yml |
6. Suporte a Python3 – Utilização da variável ansible_python_interpreter
Algumas distribuições não tem um python instalado, e sim o python3. É o caso do Ubuntu 16.
Sistema Operacional:
@lb-01:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.3 LTS Release: 16.04 Codename: xenial @lb-01:~$ python3  [tab] python3 python3.5 python3.5m python3m |
$ ansible -m command -a "hostname" lb-01.devopslab.com.br lb-01.devopslab.com.br | FAILED! => { "changed" : false , "module_stderr" : "Shared connection to lb-01.devopslab.com.br closed.\r\n" , "module_stdout" : "/bin/sh: 1: /usr/bin/python: not found\r\n" , "msg" : "MODULE FAILURE" , "rc" : 127 } |
Para resolver este pequeno problema, na definição do seu inventário, informe para que o grupo em questão utilize o python3 ou a versão do Python que você precise no momento.
/etc/ansible/hosts [loadbalancer] lb-01.devopslab.com.br [loadbalancer:vars] ansible_python_interpreter= /usr/bin/python3 |
Para validar, execute qualquer comando via ansible.
$ ansible -m command -a "hostname" lb-01.devopslab.com.br lb-01.devopslab.com.br | SUCCESS | rc=0 >> lb-01.ir7.com.br |
DOC Python3 Support:
https://docs.ansible.com/ansible/devel/reference_appendices/python_3_support.html
7. Alguns playbooks – Instalação do Apache, Nginx e Mysql.
No lab deste tutorial nós temos um LoabBalancer (Nginx), um ou mais WebServers (Apache) e um Banco de dados Mysql. Segue os Playbooks, para a instalação do Apache, Nginx e Mysql.
APACHE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
--- - hosts: webserver become: true tasks: - name: Instalacao do Apache2 e componentes adicionais apt: name={{item}} state=present update_cache=yes with_items: - apache2 - libapache2-mod-wsgi - python-pip - python-virtualenv - name: Garantir que o Apache seja iniciado service: name=apache2 state=started enabled=yes - name: habilitar o modulo mod_wsgi apache2_module: state=present name=wsgi notify: restart apache2 handlers: - name: restart apache2 service: name=apache2 state=restarted |
NGINX
1
2
3
4
5
6
7
8
9
10
|
--- - hosts: loadbalancer #"became" Utilizar o sudo become: true tasks: - name: "Instalacao do NGINX via APT" apt: name=nginx state=present update_cache=yes - name: "Nginx started" service: name=nginx state=started enabled=yes |
MYSQL
1
2
3
4
5
6
7
8
9
|
--- - hosts: database become: true tasks: - name: "Instalacao do MYSQL SERVER via APT" apt: name=mysql-server state=present update_cache=yes - name: "MYSQL started" service: name=mysql state=started enabled=yes |
8. Copia de Arquivos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
--- - hosts: webserver become: true tasks: - name: "Instalacao do Apache2 e componentes adicionais" apt: name={{item}} state=present update_cache=yes with_items: - apache2 - libapache2-mod-wsgi - python-pip - python-virtualenv - name: "Garantir que o Apache seja iniciado" service: name=apache2 state=started enabled=yes - name: "habilitar o modulo mod_wsgi" apache2_module: state=present name=wsgi notify: restart apache2 - name: "Copia de arquivos de um diretorio local para o servidor remoto" copy: src=/STORAGE/APACHE/demo/app/ dest=/var/www/demo mode=0755 notify: restart apache2 - name: "Copia do demo.conf para o servidor remoto" copy: src=/STORAGE/APACHE/demo/demo.conf dest=/etc/apache2/sites-available mode=0755 notify: restart apache2 handlers: - name: "restart apache2" service: name=apache2 state=restarted |
9. Utilização de templates
Template Nginx
Nome do template: nginx.conf.j2
#Template Nginx upstream servidoresweb { {% for server in groups.webserver %} server {{ server }}; {% endfor %} } server { listen 80; location / { proxy_pass http://servidoresweb; } } |
Onde “groups.webserver” é o grupo de servidores “webserver” definidos no arquivo “/etc/ansible/hosts“, que será utilizado no laço “for” do template recém criado “nginx.conf.j2″.
/etc/ansible/host
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
[loadbalancer] lb-01.devopslab.com.br [webserver] app-01.devopslab.com.br app-02.devopslab.com.br #[webservers] #app-03.devopslab.com.br [database] db-01.devopslab.com.br [ansible] ansiblecontrol-01.devopslab.com.br ansible_connection=local #[rundeckserver] #app-04.devopslab.com.br #VARS [database:vars] ansible_python_interpreter=/usr/bin/python3 [loadbalancer:vars] ansible_python_interpreter=/usr/bin/python3 [webserver:vars] ansible_python_interpreter=/usr/bin/python3 |
Playbook Nginx
Nome do Playbook: loadbalancer.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
--- - hosts: loadbalancer become: true tasks: - name: "instalacao do nginx" apt: name=nginx state=present update_cache=yes - name: "Start do nginx" service: name=nginx state=started enabled=yes - name: "Utilizacao do template para configuracao do virtual hosts" template: src=/STORAGE/APACHE/demo/templates/nginx.conf.j2 dest=/etc/nginx/sites-available/demo mode=0644 notify: "restart nginx" - name: "Desativacao do virtual host default no nginx" file: path=/etc/nginx/sites-enabled/default state=absent notify: "restart nginx" - name: "Criacao de um link simbolico para ativacao do novo virtual host no sites-enabled do nginx" file: src=/etc/nginx/sites-available/demo dest=/etc/nginx/sites-enabled/demo state=link notify: "restart nginx" handlers: - name: "restart nginx" service: name=nginx state=restarted |
Execução do playbook loadbalancer.yml
@ansiblecontrol-01: /etc/ansible/playbooks $ ansible-playbook loadbalancer.yml PLAY [loadbalancer] *********************************************************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************************************************************** ok: [lb-01.devopslab.com.br] TASK [instalacao do nginx] **************************************************************************************************************************************************************************************** ok: [lb-01.devopslab.com.br] TASK [Start do nginx] ********************************************************************************************************************************************************************************************* ok: [lb-01.devopslab.com.br] TASK [Utilizacao do template para configuracao do virtual hosts] ************************************************************************************************************************************************** changed: [lb-01.devopslab.com.br] TASK [Desativacao do virtual host default no nginx] *************************************************************************************************************************************************************** changed: [lb-01.devopslab.com.br] TASK [Criacao de um link simbolico para ativacao do novo virtual host no sites-enabled do nginx] ****************************************************************************************************************** changed: [lb-01.devopslab.com.br] RUNNING HANDLER [restart nginx] *********************************************************************************************************************************************************************************** changed: [lb-01.devopslab.com.br] PLAY RECAP ******************************************************************************************************************************************************************************************************** lb-01.devopslab.com.br : ok=7 changed=4 unreachable=0 failed=0 |
10. Utilização do módulo lineinfile para a configuração de arquivos
Neste caso, vou configurar o bind do Mysql com o módulo lineinfile, utilizando uma regexp.
--- - hosts: database become: true tasks: - name: "Instalacao do MYSQL SERVER via APT" apt: name=mysql-server state=present update_cache=yes - name: "MYSQL started" service: name=mysql state=started enabled=yes - name: "Utilizando uma Regexp para alterar o my.cnf e configurar o bind do Mysql" lineinfile: dest=/etc/mysql/mysql.conf.d/mysqld.cnf regexp=^bind-address line="bind-address = 0.0.0.0" notify: restart mysql handlers: - name: restart mysql service: name=mysql state=restarted |
Se for encontrada a linha começando com “bind-address”, o “bind-address” será subistituído por “bind-address = 0.0.0.0”. Ou então, caso não seja encontrado o “bind-address”, a entrada “bind-address = 0.0.0.0” será adicionada ao arquivo /etc/mysql/mysql.conf.d/mysqld.cnf.
11. Instalacão do Mysql, Banco e usuário
S.O Ubuntu 14.04.5 LTS
Playbook database.yml
--- - hosts: database become: true tasks: - name: "Instalacao do modulo - module utilizado para criacao de DBs e usuarios no Mysql" apt: "name=python-mysqldb state=present update_cache=yes" - name: "Instalacao do MYSQL SERVER via APT-GET" apt: name=mysql-server state=present update_cache=yes - name: "MYSQL com o status started e ativo/enabled no boot" service: name=mysql state=started enabled=yes - name: "Utilizando uma Regexp para alterar o my.cnf e configurar o bind do Mysql" lineinfile: dest=/etc/mysql/my.cnf regexp=^bind-address line="bind-address = 0.0.0.0" notify: restart mysql - name: "Criacao de um banco de dados - banco criado demo" mysql_db: name=demo state=present - name: "Criacao de um usuario para o banco demo - usuario demo, password demo" mysql_user: name=demo password=demo priv=demo.*:ALL host='%' state=present handlers: - name: restart mysql service: name=mysql state=restarted |
Execução do Playbook database.yml
$ ansible-playbook database.yml PLAY [database] *************************************************************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************************************************************** ok: [db-01.devopslab.com.br] TASK [Instalacao do modulo - module utilizado para criacao de DBs e usuarios no Mysql] **************************************************************************************************************************** changed: [db-01.devopslab.com.br] TASK [Instalacao do MYSQL SERVER via APT-GET] ********************************************************************************************************************************************************************* changed: [db-01.devopslab.com.br] TASK [MYSQL com o status started e ativo /enabled no boot] ********************************************************************************************************************************************************* ok: [db-01.devopslab.com.br] TASK [Utilizando uma Regexp para alterar o my.cnf e configurar o bind do Mysql] *********************************************************************************************************************************** changed: [db-01.devopslab.com.br] TASK [Criacao de um banco de dados - banco criado demo] *********************************************************************************************************************************************************** ok: [db-01.devopslab.com.br] TASK [Criacao de um usuario para o banco demo - usuario demo, password demo] ************************************************************************************************************************************** ok: [db-01.devopslab.com.br] RUNNING HANDLER [restart mysql] *********************************************************************************************************************************************************************************** changed: [db-01.devopslab.com.br] PLAY RECAP ******************************************************************************************************************************************************************************************************** db-01.devopslab.com.br : ok=8 changed=4 unreachable=0 failed=0 |
12. Roles
Roles é uma forma de se reaproveitar um código entre vários Playbooks.
Por padrão as roles ficam no diretório: /etc/ansible/roles
Para criar uma role, utilize o comando ansible-galaxy, pois já será criada toda a estrutura ideal de uma role.
#cd /etc/ansible/roles #ansible-galaxy init exemplo |
Vamos alterar o Playbook de instalação do Mysql para utilizar roles.
Playbook Mysql
--- - hosts: database become: true tasks: - name: "Instalacao do modulo - module utilizado para criacao de DBs e usuarios no Mysql" apt: "name=python-mysqldb state=present update_cache=yes" - name: "Instalacao do MYSQL SERVER via APT-GET" apt: name=mysql-server state=present update_cache=yes - name: "MYSQL com o status started e ativo/enabled no boot" service: name=mysql state=started enabled=yes - name: "Utilizando uma Regexp para alterar o my.cnf e configurar o bind do Mysql" lineinfile: dest=/etc/mysql/my.cnf regexp=^bind-address line="bind-address = 0.0.0.0" notify: restart mysql - name: "Criacao de um banco de dados - banco criado demo" mysql_db: name=demo state=present - name: "Criacao de um usuario para o banco demo - usuario demo, password demo" mysql_user: name=demo password=demo priv=demo.*:ALL host='%' state=present handlers: - name: restart mysql service: name=mysql state=restarted |
Playbook Mysql com roles
Criacão da role Mysql.
# cd /etc/ansible/roles # ansible-galaxy init mysql |
Criação da(s) task(s).
# vi /etc/ansible/roles/mysql/tasks/main.yml |
--- # tasks file for mysql - name: "Instalacao do modulo - module utilizado para criacao de DBs e usuarios no Mysql" apt: "name=python-mysqldb state=present update_cache=yes" - name: "Instalacao do MYSQL SERVER via APT-GET" apt: name=mysql-server state=present update_cache=yes - name: "Utilizando uma Regexp para alterar o my.cnf e configurar o bind do Mysql" lineinfile: dest=/etc/mysql/my.cnf regexp=^bind-address line="bind-address = 0.0.0.0" <strong> notify: restart mysql</strong> - name: "MYSQL com o status started e ativo/enabled no boot" service: name=mysql state=started enabled=yes - name: "Criacao de um banco de dados - banco criado demo" mysql_db: name=demo state=present - name: "Criacao de um usuario para o banco demo - usuario demo, password demo" mysql_user: name=demo password=demo priv=demo.*:ALL host='%' state=present |
Criação do(s) handler(s). Ação que define o restart do Mysql. O Handler foi referenciado na task acima.
# vi /etc/ansible/roles/mysql/handlers/main.yml |
--- # handlers file for mysql - name: restart mysql service: name=mysql state=restarted |
# vi /etc/ansible/roles/mysql/handlers/main.yml |
--- # handlers file for mysql - name: restart mysql service: name=mysql state=restarted |
Uma vez criado as tasks e handlers da role, basta executar o playbook.
/etc/ansible/playbooks $ ansible-playbook database.yml PLAY [database] *************************************************************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************************************************************** ok: [db-01.devopslab.com.br] TASK [mysql : Instalacao do modulo - module utilizado para criacao de DBs e usuarios no Mysql] ******************************************************************************************************************** ok: [db-01.devopslab.com.br] TASK [mysql : Instalacao do MYSQL SERVER via APT-GET] ************************************************************************************************************************************************************* ok: [db-01.devopslab.com.br] TASK [mysql : Utilizando uma Regexp para alterar o my.cnf e configurar o bind do Mysql] *************************************************************************************************************************** changed: [db-01.devopslab.com.br] TASK [mysql : MYSQL com o status started e ativo /enabled no boot] ************************************************************************************************************************************************* ok: [db-01.devopslab.com.br] TASK [mysql : Criacao de um banco de dados - banco criado demo] *************************************************************************************************************************************************** ok: [db-01.devopslab.com.br] TASK [mysql : Criacao de um usuario para o banco demo - usuario demo, password demo] ****************************************************************************************************************************** ok: [db-01.devopslab.com.br] RUNNING HANDLER [mysql : restart mysql] *************************************************************************************************************************************************************************** changed: [db-01.devopslab.com.br] PLAY RECAP ******************************************************************************************************************************************************************************************************** db-01.devopslab.com.br : ok=8 changed=2 unreachable=0 failed=0 |
13. Includes
Você pode fazer a inclusão de Playbooks dentro de outros Playbooks. Playbook exemplo lb-webserver-db.yml
--- - name: "Importacao do Playbook database.yml" import_playbook: database.yml - name: "Importacao do Playbook webserver.yml" import_playbook: webserver.yml - name: "Importacao do Playbook loadbalancer.yml" import_playbook: loadbalancer.yml #Restante do Playbook. # # |
14. Variáveis – Facts
Consulte todas as informações dos hosts, como CPU, memória, interfaces de rede, detalhes do kernel, OS family, e muito mais.
ansible -m setup db-01.devopslab.com.br |
Como utilizar uma informação “fact” como variável de um playbook.
Verifique as informações relativas a interface eth0
ansible -m setup db-01.devopslab.com.br ... "<strong>ansible_eth0</strong>": { "active": true, "device": "eth0", ... ... ... "<strong>ipv4</strong>": { "<strong>address</strong>": "10.0.2.26", "broadcast": "10.0.2.255", "netmask": "255.255.255.0", "network": "10.0.2.0" }, Defina a utilização do fact entre<strong> {{ }}</strong>. |
- name: "Utilizando uma Regexp para alterar o my.cnf e configurar o bind do Mysql" lineinfile: dest=/etc/mysql/my.cnf regexp=^bind-address line="bind-address = <strong>{{ ansible_eth0.ipv4.address }}</strong>" notify: restart mysql |