
рдпрд╣ DevOps-40 2020-03-18 рдкрд░ рдкреНрд░рджрд░реНрд╢рди рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рд╣реИ :
рджреВрд╕рд░реА рдкреНрд░рддрд┐рдмрджреНрдз рд╕реЗ рд╢реБрд░реВ рд╣реЛрдХрд░, рдХреЛрдИ рднреА рдХреЛрдб рд╡рд┐рд░рд╛рд╕рдд рдмрди рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд┐рдЪрд╛рд░ рдХрдареЛрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХрддрд╛ рд╕реЗ рдЕрд▓рдЧ рд╣реЛрдиреЗ рд▓рдЧрддреЗ рд╣реИрдВред рдпрд╣ рди рддреЛ рдЕрдЪреНрдЫрд╛ рд╣реИ рдФрд░ рди рд╣реА рдмреБрд░рд╛ рд╣реИ, рдпрд╣ рдПрдХ рдРрд╕рд╛ рддрд░реНрдХ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдмрд╣рд╕ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ рдФрд░ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдПрдХ рд╣рд┐рд╕реНрд╕рд╛ рд░рд┐рдлреИрдХреНрдЯрд┐рдВрдЧ рд╣реИред рдХреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рдЗрдиреНрдлреНрд░рд╛рд╕реНрдЯреНрд░рдХреНрдЪрд░ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдирд╛ред рдПрдХ рд╕рд╛рд▓ рдореЗрдВ рдХрд╣рд╛рдиреА рдХреЛ рдХреИрд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЬрд╛рдП рдФрд░ рдХреЛрдпрд▓реЛрдВ тАЛтАЛрдХреЛ рди рдЙрдбрд╝рд╛рдПрдВ, рдЗрд╕рдХреА рдХрд╣рд╛рдиреА рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
рдж рд▓рд┐рдЧреЗрд╕реА рдУрд░рд┐рдЬрд┐рди
рджрд┐рди 1: рд╢реВрдиреНрдп рд░реЛрдЧреА

рдПрдХ рдмрд╛рд░ рдПрдХ рд╕рд╢рд░реНрдд рдкрд░рд┐рдпреЛрдЬрдирд╛ рдереАред рдЗрд╕рдореЗрдВ рдПрдХ рджреЗрд╡ рд╡рд┐рдХрд╛рд╕ рджрд▓ рдФрд░ рдСрдкреНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░ рдереЗред рдЙрдиреНрд╣реЛрдВрдиреЗ рдПрдХ рд╣реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛: рд╕рд░реНрд╡рд░ рдХреЛ рдХреИрд╕реЗ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рдЬрд╛рдП рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдХреИрд╕реЗ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рдПред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рдереА рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЯреАрдо рдиреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдЕрдкрдиреЗ рддрд░реАрдХреЗ рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ред рджреЗрд╡ рдФрд░ рдСрдкреНрд╕ рдЯреАрдореЛрдВ рдХреЗ рдмреАрдЪ рдЬреНрдЮрд╛рди рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдиреЗ рдЕрдВрд╕рд┐рдмрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред
рджрд┐рди рдирдВрдмрд░ 89: рд╡рд┐рд░рд╛рд╕рдд рдХрд╛ рдЬрдиреНрдо

, , legacy. ?
- , тАФ .
- .
- Ansible / Python / Bash / Terraform! !
- Full Stack Overflow Developer stackoverflow, , .
, , , , , , , , .
- hosts: localhost
tasks:
- shell: echo -n Z >> a.txt && cat a.txt
register: output
delay: 1
retries: 5
until: not output.stdout.find("ZZZ")
тДЦ 109:

IaC / / , . , .
IaC
тДЦ 139: ?

:
- ?
- ?
- ?
, . .. ( , 200 000 ), .
тДЦ 149:

e . . , . - , confluence, " ?" " ?" . : / . , , - .

, . , , : , , .
Ansible
Ansible , , .
тДЦ -997: SDS provision

Ansible SDS (Software Defined Storage).
, , 60-90 , . e2e , .. , . . .
тДЦ -701: Ansible test kitchen

Ansible , test kitchen / kitchen-ci inspec. Ruby ( : YML ansible?) 40 10 . .

, - . 13 2 , 70 , 2 . XP (extreme programming) .. 70 .
тДЦ -601: Ansible molecule

testkitchen, docker . , 20-25 7 .

17 45 28 2 jenkins slave.
тДЦ 167: Ansible

, . , . , .

, , , jira, google docs . , , . , - , , .
:
- Eat.
- Sleep.
- Code.
- IaC test.
- Repeat
.

, .
тДЦ 181: Green Build Master

Green Build Master. , jenkins. , :
тДЦ 193: unit

тАФ , . , .
тДЦ 211: unit integration

unit , . .. , , .

jenkins , / , .
Jenkins + Docker + Ansible = Tests

- Checkout repo and generate build stages.
- Run lint playbook stages in parallel.
- Run lint role stages in parallel.
- Run syntax check role stages in parallel.
- Run test role stages in parallel.
- Lint role.
- Check dependency on other roles.
- Check syntax.
- Create docker instance
- Run molecule/default/playbook.yml.
- Check idempotency.
- Run integration tests
- Finish
тДЦ 271: Bus Factor

- . e. code review . , , , .. .

. , , . jenkins + bitbucket + jira.
, -, , :
- get_url:
url: "{{ actk_certs }}/{{ item.1 }}"
dest: "{{ actk_src_tmp }}/"
username: "{{ actk_mvn_user }}"
password: "{{ actk_mvn_pass }}"
with_subelements:
- "{{ actk_cert_list }}"
- "{{ actk_certs }}"
delegate_to: localhost
- copy:
src: "{{ actk_src_tmp }}/{{ item.1 }}"
dest: "{{ actk_dst_tmp }}"
with_subelements:
- "{{ actk_cert_list }}"
- "{{ actk_certs }}"
, .
get_url:
url: "{{ actk_certs }}/{{ actk_item }}"
dest: "{{ actk_src_tmp }}/{{ actk_item }}"
username: "{{ actk_mvn_user }}"
password: "{{ actk_mvn_pass }}"
loop_control:
loop_var: actk_item
with_items: "{{ actk_cert_list }}"
delegate_to: localhost
- copy:
src: "{{ actk_src_tmp }}/{{ actk_item }}"
dest: "{{ actk_dst_tmp }}"
loop_control:
loop_var: actk_item
with_items: "{{ actk_cert_list }}"
тДЦ 311:

, . " , ". docker, . testinfra ansible verifier - .

:
- docker.
- , .
- - .
- .
- .

Pipeline jenkins
- Generate build stages.
- Lint all in parallel.
- Run test role stages in parallel.
- Finish.
Lessons learned
Avoid global variables
Ansible , workaround private_role_vars, .
. role_a
role_b
# cat role_a/defaults/main.yml
---
msg: a
# cat role_a/tasks/main.yml
---
- debug:
msg: role_a={{ msg }}
# cat role_b/defaults/main.yml
---
msg: b
# cat role_b/tasks/main.yml
---
- set_fact:
msg: b
- debug:
msg: role_b={{ msg }}
- hosts: localhost
vars:
msg: hello
roles:
- role: role_a
- role: role_b
tasks:
- debug:
msg: play={{msg}}

, , . Ansible , - , .
BAD: .
# cat roles/some_role/tasks/main.yml
---
debug:
var: java_home
GOOD: defaults
.
# cat roles/some_role/defaults/main.yml
---
r__java_home:
"{{ java_home | default('/path') }}"
# cat roles/some_role/tasks/main.yml
---
debug:
var: r__java_home
Prefix role variables
BAD: .
# cat roles/some_role/defaults/main.yml
---
db_port: 5432
GOOD: , inventory .
# cat roles/some_role/defaults/main.yml
---
some_role__db_port: 5432
Use loop control variable
BAD: item
, / -
---
- hosts: localhost
tasks:
- debug:
msg: "{{ item }}"
loop:
- item1
- item2
GOOD: loop_var
.
---
- hosts: localhost
tasks:
- debug:
msg: "{{ item_name }}"
loop:
- item1
- item2
loop_control:
loop_var: item_name
, , ,
GOOD: .
- name: "Verify that required string variables are defined"
assert:
that: ahs_var is defined and ahs_var | length > 0 and ahs_var != None
fail_msg: "{{ ahs_var }} needs to be set for the role to work "
success_msg: "Required variables {{ ahs_var }} is defined"
loop_control:
loop_var: ahs_var
with_items:
- ahs_item1
- ahs_item2
- ahs_item3
Avoid hashes dictionaries, use flat structure
hash/dictionary , , hash/dictionary, .
BAD: hash/dictionary.
---
user:
name: admin
group: admin
GOOD: .
---
user_name: admin
user_group: "{{ user_name }}"
Create idempotent playbooks & roles
, .. configuration drift -. molecule, .
Avoid using command shell modules
shell , , Ansible.
Test your roles via molecule
Molecule , .
Molecule Multiple instances
molecule.yml
platforms
.
---
driver:
name: docker
platforms:
- name: postgresql-instance
hostname: postgresql-instance
image: registry.example.com/postgres10:latest
pre_build_image: true
override_command: false
network_mode: host
- name: app-instance
hostname: app-instance
pre_build_image: true
image: registry.example.com/docker_centos_ansible_tests
network_mode: host
, converge.yml
:
---
- name: Converge all
hosts: all
vars:
ansible_user: root
roles:
- role: some_role
- name: Converge db
hosts: db-instance
roles:
- role: some_db_role
- name: Converge app
hosts: app-instance
roles:
- role: some_app_role
Ansible verifier
molecule ansible , , 3 . testinfra/inspec, , :
---
- name: Verify
hosts: all
tasks:
- name: copy config
copy:
src: expected_standalone.conf
dest: /root/wildfly/bin/standalone.conf
mode: "0644"
owner: root
group: root
register: config_copy_result
- name: Certify that standalone.conf changed
assert:
that: not config_copy_result.changed
, smoke test:
---
- name: Verify
hosts: solr
tasks:
- command: /blah/solr/bin/solr start -s /solr_home -p 8983 -force
- uri:
url: http://127.0.0.1:8983/solr
method: GET
status_code: 200
register: uri_result
until: uri_result is not failed
retries: 12
delay: 10
- name: Post documents to solr
command: /blah/solr/bin/post -c master /exampledocs/books.csv
Put complex logic into modules & plugins
Ansible , , , shell , . , , .
Summarize Tips & Tricks
- Avoid global variables.
- Prefix role variables.
- Use loop control variable.
- Check input variables.
- Avoid hashes dictionaries, use flat structure.
- Create idempotent playbooks & roles.
- Avoid using command shell modules.
- Test your roles via molecule.
- Put complex logic into modules & plugins.

, IaC. , .
Links
UPD1 2020.05.01 20:30 тАФ callback_whitelist = profile_tasks
. ansible. mitogen
UPD2 2020.05.03 16:34 тАФ English version