Ansible Advanced: Edasijõudnud Funktsioonid¶
Navigeerimine
Kasuta paremal olevat sisukorda kiireks navigeerimiseks ↗️
Teemad: Variables, Templates, Handlers, Vault
Õpiväljundid¶
Pärast seda nädalat oskate: - Hallata keerukamaid muutujaid ja nende hierarhiat - Luua dünaamilisi konfiguratsioone Jinja2 template'itega - Kasutada handler'eid efektiivseks teenuste haldamiseks - Rakendada Ansible Vault'i tundlike andmete kaitsmiseks - Järgida Ansible best practice'sid
1. Variables ja Variable Precedence¶
1.1 Muutujate hierarhia¶
Ansible'is on muutujatel kindel prioriteedi järjekord:
graph TD
A[1. Command line<br/>-e, --extra-vars] --> B[2. Task variables<br/>task sees]
B --> C[3. Block variables<br/>block sees]
C --> D[4. Role variables<br/>role/vars/main.yml]
D --> E[5. Play variables<br/>playbook sees]
E --> F[6. Host variables<br/>host_vars/]
F --> G[7. Group variables<br/>group_vars/]
G --> H[8. Role defaults<br/>role/defaults/main.yml]
style A fill:#ff9999
style B fill:#ffcc99
style C fill:#ffff99
style D fill:#99ff99
style E fill:#99ccff
style F fill:#cc99ff
style G fill:#ff99cc
style H fill:#99ffcc
```text
**Prioriteedi järjekord (kõrgeim esimesena):**
1. **Command line** (`-e`, `--extra-vars`)
2. **Task variables** (task sees)
3. **Block variables** (block sees)
4. **Role variables** (role/vars/main.yml)
5. **Play variables** (playbook sees)
6. **Host variables** (host_vars/)
7. **Group variables** (group_vars/)
8. **Role defaults** (role/defaults/main.yml)
**Näide muutujate konfliktist:**
```yaml
# group_vars/all.yml
server_port: 80
# host_vars/webserver1.yml
server_port: 8080
# playbook.yml
- name: "Server setup"
vars:
server_port: 3000
tasks:
- debug:
msg: "Port will be: {{ server_port }}" # Tulemus: 3000
```bash
🤔 **Realiteedikontroll:** Kui teil on 100 serverit ja igal on erinev konfiguratsioon, kuidas te seda ilma muutujate hierarhiata hallaksite?
### 1.2 Faktide kasutamine
Ansible kogub automaatselt süsteemi infot:
```yaml
- name: "Näita süsteemi faktid"
debug:
msg:
- "OS: {{ ansible_os_family }}"
- "Memory: {{ ansible_memtotal_mb }}MB"
- "CPU cores: {{ ansible_processor_vcpus }}"
- "IP: {{ ansible_default_ipv4.address }}"
```text
### 1.3 Registered variables
Salvestage käsu tulemusi:
```yaml
- name: "Kontrolli Apache staatust"
shell: "systemctl is-active apache2"
register: apache_status
failed_when: false
- name: "Tegevus Apache staatuse põhjal"
debug:
msg: "Apache on {{ apache_status.stdout }}"
when: apache_status.rc == 0
```text
---
## 2. Jinja2 Templates
### 2.1 Template'ite põhitõed
Jinja2 võimaldab luua dünaamilisi faile:
```yaml
# Playbook task
- name: "Genereeri konfiguratsioon"
template:
src: app.conf.j2
dest: /etc/app/config.conf
```text
**Template fail (`templates/app.conf.j2`):**
```ini
# {{ ansible_managed }}
server_name = {{ inventory_hostname }}
port = {{ server_port | default(80) }}
debug = {{ debug_mode | default(false) | lower }}
# Environment specific
{% if environment == 'production' %}
log_level = ERROR
cache_enabled = true
{% else %}
log_level = DEBUG
cache_enabled = false
{% endif %}
```text
**Küsimus:** Miks on kasulik kasutada `{{ ansible_managed }}` kommentaari template'i alguses?
### 2.2 Conditionals template'ites
```jinja2
{% if ansible_os_family == "Debian" %}
package_manager = apt
{% elif ansible_os_family == "RedHat" %}
package_manager = yum
{% else %}
package_manager = unknown
{% endif %}
# Inline conditionals
service_port = {{ 443 if ssl_enabled else 80 }}
```text
🤔 **Mõelge:** Kuidas aitavad conditionals hallata erinevaid operatsioonisüsteeme ühes template'is?
### 2.3 Loops template'ites
```jinja2
# Virtual hosts
{% for host in virtual_hosts %}
<VirtualHost *:{{ host.port }}>
ServerName {{ host.name }}
DocumentRoot {{ host.document_root }}
{% if host.ssl_enabled | default(false) %}
SSLEngine on
SSLCertificateFile {{ host.ssl_cert }}
{% endif %}
</VirtualHost>
{% endfor %}
# Database users
{% for user in database_users %}
CREATE USER '{{ user.name }}'@'{{ user.host }}' IDENTIFIED BY '{{ user.password }}';
GRANT {{ user.privileges | join(', ') }} ON {{ user.database }}.* TO '{{ user.name }}'@'{{ user.host }}';
{% endfor %}
```text
📊 **Võrdlus:** Võrrelge template'i kasutamist staatilise konfiguratsiooniga. Millised on eelised ja puudused?
### 2.4 Filters
```jinja2
# String manipulation
server_name = {{ inventory_hostname | upper }}
config_file = {{ app_name | lower }}.conf
# Number operations
memory_limit = {{ (ansible_memtotal_mb * 0.8) | int }}M
worker_processes = {{ ansible_processor_vcpus | default(1) }}
# List operations
packages = {{ required_packages | join(' ') }}
first_server = {{ groups['webservers'] | first }}
# JSON/YAML
config = {{ app_config | to_nice_json }}
```text
**Praktiline nipp:** Kasutage `| default()` filter'it vaikeväärtuste määramiseks template'ites.
---
## 3. Handlers ja Notifications
### 3.1 Handler'ite põhitõed
Handler'id käivituvad ainult siis, kui task teeb muudatusi:
```yaml
tasks:
- name: "Uuenda Apache konfiguratsioon"
template:
src: apache.conf.j2
dest: /etc/apache2/apache2.conf
notify: "restart apache"
- name: "Lisa virtual host"
template:
src: vhost.conf.j2
dest: "/etc/apache2/sites-available/{{ site_name }}.conf"
notify:
- "enable site"
- "reload apache"
handlers:
- name: "restart apache"
service:
name: apache2
state: restarted
- name: "reload apache"
service:
name: apache2
state: reloaded
- name: "enable site"
command: "a2ensite {{ site_name }}"
```text
🤔 **Mõelge:** Miks kasutada `reload` mitte `restart`? Millal on vahe oluline?
### 3.2 Handler'ite täiustatud kasutamine
**Listen groups:**
```yaml
tasks:
- name: "Uuenda PHP konfiguratsioon"
template:
src: php.ini.j2
dest: /etc/php/7.4/fpm/php.ini
notify: "restart web services"
- name: "Uuenda Apache konfiguratsioon"
template:
src: apache.conf.j2
dest: /etc/apache2/apache2.conf
notify: "restart web services"
handlers:
- name: "restart php-fpm"
service:
name: php7.4-fpm
state: restarted
listen: "restart web services"
- name: "restart apache"
service:
name: apache2
state: restarted
listen: "restart web services"
```bash
**Küsimus:** Mis järjekorras käivituvad handler'id ja miks see on oluline?
🎯 **Praktikasoovitus:** Kasutage `meta: flush_handlers` kriitiliste kontrollidel, kui peate veenduma, et teenus on taaskäivitatud enne järgmisi task'e.
---
## 4. Ansible Vault Secrets
### 4.1 Vault'i põhitõed
Ansible Vault krüpteerib tundlikud andmed:
```bash
# Loo krüpteeritud fail
ansible-vault create secrets.yml
# Muuda krüpteeritud faili
ansible-vault edit secrets.yml
# Vaata krüpteeritud faili
ansible-vault view secrets.yml
# Krüpteeri olemasolev fail
ansible-vault encrypt plaintext.yml
# Dekrüpteeri fail
ansible-vault decrypt secrets.yml
```text
**Näide vault failis:**
```yaml
# secrets.yml (krüpteeritud)
vault_db_password: "supersecretpassword123"
vault_api_key: "abc123def456ghi789"
vault_ssl_private_key: |
-----BEGIN PRIVATE KEY-----
[private key content]
-----END PRIVATE KEY-----
```text
🔐 **Turvanipp:** Vault'i parool peaks olema vähemalt 12 tähemärki ja sisaldama erinevaid sümboleid.
### 4.2 Vault'i kasutamine playbook'ides
```yaml
# group_vars/production/vault.yml (krüpteeritud)
vault_mysql_root_password: "production_mysql_secret"
vault_app_secret_key: "prod_app_key_123456"
# group_vars/production/vars.yml (avatud)
mysql_root_password: "{{ vault_mysql_root_password }}"
app_secret_key: "{{ vault_app_secret_key }}"
environment: "production"
```text
**Playbook käivitamine:**
```bash
# Küsi parooli
ansible-playbook site.yml --ask-vault-pass
# Kasuta parool faili
echo "mypassword" > .vault_pass
ansible-playbook site.yml --vault-password-file .vault_pass
```text
🤔 **Mõelge:** Kuidas saaksite organisatsioonis turvaliselt jagada vault paroole?
### 4.3 Multiple vault passwords
```bash
# Erinev vault erinevale keskkonnale
ansible-vault create --vault-id prod@prompt production-secrets.yml
ansible-vault create --vault-id dev@prompt development-secrets.yml
# Käivitamine
ansible-playbook site.yml --vault-id prod@prompt --vault-id dev@prompt
```text
### 4.4 Vault parooli haldamine
**Environment variable:**
```bash
export ANSIBLE_VAULT_PASSWORD=mypassword
ansible-playbook site.yml
```text
**Script'iga:**
```bash
#!/bin/bash
# vault_pass.sh
echo "my_secret_password"
chmod +x vault_pass.sh
ansible-playbook site.yml --vault-password-file vault_pass.sh
```text
💭 **Küsimus:** Mis probleeme võib tekkida vault paroolide haldamisel meeskonnatöös?
### 4.5 Vault'i rekey
```bash
# Muuda vault parooli
ansible-vault rekey secrets.yml
# Muuda spetsiifilise vault'i parooli
ansible-vault rekey --vault-id old@prompt --new-vault-id new@prompt secrets.yml
```text
**Praktiline nipp:** Regulaarselt muutke vault paroole ja dokumenteerige rotatsiooni protseduuri.
### 4.6 Best practices
#### 4.6.1 Vault failide organisatsioon
group_vars/
├── all/
│ ├── vars.yml # Avalikud muutujad
│ └── vault.yml # Krüpteeritud saladused
├── production/
│ ├── vars.yml
│ └── vault.yml
└── development/
├── vars.yml
└── vault.yml
```text
🤔 Mõelge: Kuidas organiseerida vault faile nii, et oleks selge, millised andmed on krüpteeritud ja millised mitte?
4.6.2 Vault rotatsiooni strateegi¶
```bash
Regulaarne parooli vahetamine (näiteks kvartaalselt)¶
1. Loo uus vault parool¶
ansible-vault rekey --new-vault-password-file new_password production-secrets.yml
2. Uuenda CI/CD süsteemid uue parooliga¶
3. Teavita meeskonda muudatusest¶
4. Eemalda vana parool kõigist süsteemidest¶
```bash
5. Lab: Template-based Configuration¶
Käed-küljes praktikum Ansible'i täpsemate funktsioonidega tutvumiseks.
📁 Vaata: lab.md
Sisaldab:
- Advanced variables setup
- Jinja2 template'ite loomine
- Handlers ja advanced playbook'id
- Ansible Vault rakendamine