
Dalam tutorial ini, kita akan belajar cara menguji kode framework yang ditulis dalam Ansible menggunakan framework pengujian yang dikenal sebagai Molecule. Di dalam Molecule, kita akan menggunakan Ansible sebagai pemverifikasi, yang tidak dapat saya temukan di tempat lain. Ayo lakukan!
Kandungan
- pengantar
- Menginstal Molekul
- Molecule Ansible
- Ansible Ansible Verifier
Ansible โ , , , , . , . -.
, . . , , , , .
Molecule โ , Ansible. 26 Ansible Molecule Ansible-lint Red Hat Ansible. Red Hat , , .
Molecule , , , .
Molecule TDD- . , , , Molecule.
Molecule
, UNIX.
Molecule :
- Python 2.7 Python 3.5 ( Python 3.7)
- Ansible 2.5 ( Ansible 2.9.6)
- Docker ( )
Pip โ Molecule. Python 2.7.9 ( ) Python 3.4 ( ), PIP Python.
Molecule pip:
$ pip3 install molecule
. ยซ Moleculeยป. , Molecule, $ molecule --version.
Ansible Playbooks , , Ansible , .. Ansible , , , , , , , Ansible, , , โ , , (, ).
Molecule Ansible
Molecule Ansible:
. Molecule Ansible
Molecules Ansible Galaxy Ansible. Molecule:
$ molecule init role <the_role_name>
. Initiating Ansible
Molecule , , , , , :
$ molecule init scenario -r <the_already_existing_role_name>
, Molecule, Molecule . :
.
โโโ README.md
โโโ files/
โโโ handlers/
โโโ meta/
โโโ tasks/
โโโ templates/
โโโ tests/
โโโ vars/
โโโ molecule/
โโโ default
โโโ molecule.yml
โโโ converge.yml
โโโ verify.yml
โโโ INSTALL.rst
Molecule :
molecule.yml
molecule.yml Molecule, .
---
dependency:
name: galaxy
enabled: true # to disable, set to false
driver:
name: docker
platforms:
- name: instance
image: docker.io/pycontribs/centos:7
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansible
dependency:
, . Ansible Galaxy โ , Molecule. โ Shell Gilt. dependency true, , enabled false.
driver:
Molecule, . Molecule โ Docker, , : AWS, Azure, Google Cloud, Vagrant, Hetzner Cloud . . Molecule .
platforms:
, . , , , , .
provisioner:
Provider โ , converge.yml ( ). โ Ansible.
verifier:
verifier โ , . verify.yml, , ( ) ( ). โ Ansible, , : testinfra, goss inspec. testinfra , - UX , Python, testinfra , Ansible , . git issue .
, , โ lint . Molevel.yml .
lint:
Lint , Molecule , , , . โ yamllint, ansible-lint, flake8 .
scenario:
Molecule. , , . , .
, โ , Molecule. , :
scenario:
create_sequence:
- dependency
- create
- prepare
check_sequence:
- dependency
- cleanup
- destroy
- create
- prepare
- converge
- check
- destroy
converge_sequence:
- dependency
- create
- prepare
- converge
destroy_sequence:
- dependency
- cleanup
- destroy
test_sequence:
- dependency
- lint
- cleanup
- destroy
- syntax
- create
- prepare
- converge
- idempotence
- side_effect
- verify
- cleanup
- destroy
, , Molecule, , $ molecule create , create_sequence, $ molecule check check_sequence .
, , , , , , .
Converge.yml
converge.yml, , , . . , $ molecule converge.
verify.yml
verify.yml , . , . , $ molecule verify.
INSTALL.rst
, Molecule .
Ansible Ansible Verifier
, , , Ansible Ansible Molecule.
$ molecule test test_sequence, , , , , .
, , BDD, :
# given phase
$ molecule create
# when phase
$ molecule converge
# then phase
$ molecule verify
, () . , .
โ TDD . . , alpha-services, :
- 1. Java-1.8 -.
- 2:
/var/log/tomcat,tomcat,tomcat0755 - 3. , httpd
- 4.
template/tomcat/context.xml/etc/tomcat/context.xml
, Molecule :
$ molecule init role alpha-services
, . alpha-services/molecule/default/roles/test_alpha-services:
$ cd alpha-services
$ mkdir -p molecule/default/roles/test_alpha-services
. test_alpha-services
, Ansible ( , , , ). main.yml. yml, , test_. , java test_java.yml.
$ cd molecule/default/roles/test_alpha-services
$ mkdir defaults && touch defaults/main.yml
$ mkdir tasks && touch tasks/main.yml tasks/test_java.yml tasks/test_tomcat.yml tasks/test_httpd.yml tasks/test_aws.yml
$ mkdir vars && touch vars/main.yml
:
alpha-services/
โโโ README.md
โโโ files/
โโโ handlers/
โโโ meta/
โโโ tasks/
โโโ templates/
โโโ tests/
โโโ vars/
โโโ molecule/
โโโ default
โโโ molecule.yml
โโโ converge.yml
โโโ verify.yml
โโโ INSTALL.rst
โโโ roles/
โโโ test_alpha-services/
โโโ defaults/
โโโ main.yml
โโโ tasks/
โโโ main.yml
โโโ test_java.yml
โโโ test_tomcat.yml
โโโ test_httpd.yml
โโโ test_aws.yml
โโโ vars/
โโโ main.yml
molecule.yml:
---
dependency:
name: galaxy
enabled: false
driver:
name: docker
platforms:
- name: instance
image: docker.io/pycontribs/centos:7
pre_build_image: true
provisioner:
name: ansible
verifier:
name: ansible
converge.yml :
---
- name: Converge
hosts: all
tasks:
- name: "Include alpha-services"
include_role:
name: "alpha-services"
verify.yaml, :
---
# This is an example playbook to execute Ansible tests.
- name: Verify
hosts: all
tasks:
- name: "Include test_alpha-services"
include_role:
name: "test_alpha-services"
GIVEN : $ molecule create .
$ molecule create
--> Test matrix
โโโ default
โโโ dependency
โโโ create
โโโ prepare
--> Scenario: 'default'
--> Action: 'dependency'
Skipping, dependency is disabled.
--> Scenario: 'default'
--> Action: 'create'
--> Sanity checks: 'docker'
PLAY [Create] ******************************************************************
TASK [Log into a Docker registry] **********************************************
skipping: [localhost] => (item=None)
TASK [Check presence of custom Dockerfiles] ************************************
ok: [localhost] => (item=None)
ok: [localhost]
TASK [Create Dockerfiles from image names] *************************************
skipping: [localhost] => (item=None)
TASK [Discover local Docker images] ********************************************
ok: [localhost] => (item=None)
ok: [localhost]
TASK [Build an Ansible compatible image (new)] *********************************
skipping: [localhost] => (item=molecule_local/docker.io/pycontribs/centos:7)
TASK [Create docker network(s)] ************************************************
TASK [Determine the CMD directives] ********************************************
ok: [localhost] => (item=None)
ok: [localhost]
TASK [Create molecule instance(s)] *********************************************
changed: [localhost] => (item=instance)
TASK [Wait for instance(s) creation to complete] *******************************
FAILED - RETRYING: Wait for instance(s) creation to complete (300 retries left).
changed: [localhost] => (item=None)
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=5 changed=2 unreachable=0 failed=0 skipped=4 rescued=0 ignored=0
--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.
WHEN : $ molecule converge , . .
$ molecule converge
--> Test matrix
โโโ default
โโโ dependency
โโโ create
โโโ prepare
โโโ converge
--> Scenario: 'default'
--> Action: 'dependency'
Skipping, dependency is disabled.
--> Scenario: 'default'
--> Action: 'create'
Skipping, instances already created.
--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.
--> Scenario: 'default'
--> Action: 'converge'
--> Sanity checks: 'docker'
PLAY [Converge] ****************************************************************
TASK [Gathering Facts] *********************************************************
ok: [instance]
TASK [Include alpha-services] **************************************************
TASK [alpha-services : include java installation tasks] ************************
included: /Users/chukwudiuzoma/Documents/DevOps/ANSIBLE/MyTutorials/AnsibleTestingWithMolecule/alpha-services/tasks/java.yml for instance
TASK [alpha-services : Install java] *******************************************
changed: [instance]
PLAY RECAP *********************************************************************
instance : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
.
TDD, , , , .
1. Java-1.8.0 -
---
- name: "java - check Java package status"
package:
name: "java-1.8.0"
state: "installed"
check_mode: yes
register: pkg_status
- name: "java - test java package is installed"
assert:
that:
- not pkg_status.changed
Java java-1.8.0 pkg_status. , java-1.8.0 , not pkg_status.changed true, . .
test_java.yml alpha-services/molecule/default/roles/test_alpha-services/tasks/main.yml :
---
- name: "include tasks for testing Java"
include_tasks: "test_java.yml"
THEN : $ molecule verify. , :
$ molecule verify
--> Test matrix
โโโ default
โโโ verify
--> Scenario: 'default'
--> Action: 'verify'
--> Running Ansible Verifier
--> Sanity checks: 'docker'
PLAY [Verify] ******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [instance]
TASK [Include test_alpha-services] *********************************************
TASK [test_alpha-services : include tasks for testing Java] ********************
included: /Users/chukwudiuzoma/Documents/DevOps/ANSIBLE/MyTutorials/AnsibleTestingWithMolecule/alpha-services/molecule/default/roles/test_alpha-services/tasks/test_java.yml for instance
TASK [test_alpha-services : Check Java package status] *************************
changed: [instance]
TASK [test_alpha-services : Test java package is installed] ********************
fatal: [instance]: FAILED! => {
"assertion": "not pkg_status.changed",
"changed": false,
"evaluated_to": false,
"msg": "Assertion failed"
}
PLAY RECAP *********************************************************************
instance : ok=3 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
ERROR:
1. alpha-services/tasks/java.yml :
---
- name: "Install '{{ java_required_software }}'"
package:
name: "{{ java_required_software }}"
lock_timeout: 60
state: "present"
java.yml alpha-services/tasks/main.yml :
---
- name: "Include java installation tasks"
include_tasks: "java.yml"
WHEN : $ molecule converge, .
THEN : $ molecule verify, , .
$ molecule verify
--> Test matrix
โโโ default
โโโ verify
--> Scenario: 'default'
--> Action: 'verify'
--> Running Ansible Verifier
--> Sanity checks: 'docker'
PLAY [Verify] ******************************************************************
TASK [Gathering Facts] *********************************************************
ok: [instance]
TASK [Include test_alpha-services] *********************************************
TASK [test_alpha-services : include tasks for testing Java] ********************
included: /Users/chukwudiuzoma/Documents/DevOps/ANSIBLE/MyTutorials/AnsibleTestingWithMolecule/alpha-services/molecule/default/roles/test_alpha-services/tasks/test_java.yml for instance
TASK [test_alpha-services : Check Java package status] *************************
ok: [instance]
TASK [test_alpha-services : Test java package is installed] ********************
ok: [instance] => {
"changed": false,
"msg": "All assertions passed"
}
PLAY RECAP *********************************************************************
instance : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Verifier completed successfully.
2. /var/log/tomcat, tomcat, tomcat 0755.
---
- name: "tomcat - '{{ test_tomcat_home_dir }}' - retrieve information from path"
stat:
path: "{{ test_tomcat_home_dir }}"
register: directory
- name: "tomcat - assert that directory '{{ test_tomcat_home_dir }}' is created correctly"
assert:
that:
- "directory.stat.exists"
- "directory.stat.isdir"
- "directory.stat.mode == {{ test_tomcat_mode }}"
- "directory.stat.pw_name == {{ test_tomcat_user }}"
- "directory.stat.gr_name == {{ test_tomcat_group}}"
yml- Molecule:
---
#TOMCAT
test_tomcat_mode: "0755"
test_tomcat_user: "tomcat"
test_tomcat_group: "tomcat"
test_tomcat_home_dir: "/var/log/tomcat"
stat Ansible , .
test_java.yml alpha-services/molecule/default/roles/test_alpha-services/tasks/main.yml :
---
- name: "include tasks for testing Tomcat"
include_tasks: "test_tomcat.yml"
$ molecule verify, , . :
---
- name: "tomcat - create required tomcat logging directory"
file:
path: "{{ tomcat_home_dir }}"
state: "directory"
mode: "0755"
owner: "{{ tomcat_user }}"
group: "{{ tomcat_group }}"
recurse: yes
yml :
---
#TOMCAT
tomcat_mode: "0755"
tomcat_user: "tomcat"
tomcat_group: "tomcat"
tomcat_home_dir: "/var/log/tomcat"
tomcat.yml alpha-services/tasks/main.yml :
---
- name: "Include java installation tasks"
include_tasks: "java.yml"
: $ molecule converge, .
: $ molecule verify, , .
3: , httpd
, Ansible . Ansible, ยซ Ansible โ . , , , - . Ansible โ , ยป.
, , , , :
TASK [alpha-services : httpd - start and enable httpd service] *****************
fatal: [instance]: FAILED! => {"changed": false, "msg": "Could not find the requested service httpd: host"}
:
---
- name: "Httpd - install httpd service"
package:
name: "httpd"
state: "latest"
- name: "Httpd - start and enable httpd service"
service:
name: "httpd"
state: "started"
enabled: "yes"
, httpd Linux systemd, . , platforms Molelele.yml:
---
platforms:
- name: instance
image: docker.io/pycontribs/centos:7
pre_build_image: false # we don't need ansible installed on the instance
command: /sbin/init
tmpfs:
- /run
- /tmp
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
privileged: true
systemd https://molecule.readthedocs.io/en/latest/examples.html
$ molecule create $ molecule converge. , httpd . httpd, :
$ molecule login # this logs you into the docker container shell
$ systemctl | grep httpd
httpd.service loaded active running The Apache HTTP Server
$ exit # this logs you out of the docker container to your local terminal
4. template/tomcat/context.xml /etc/tomcat/context.xml.
, , -. , , , - , . , , . , , Ansible .
:
- name: "tomcat - test tomcat file"
block:
- name: "tomcat - retrieve information from path '{{ test_tomcat_context_xml_file }}'"
stat:
path: "{{ test_tomcat_context_xml_file }}"
register: remote_file
- name: "tomcat - assert that '{{ test_tomcat_context_xml_file }}' file is created correctly"
assert:
that:
- "remote_file.stat.exists"
- "remote_file.stat.isreg" # is a regular file
- "remote_file.stat.path == '{{ test_tomcat_context_xml_file }}'"
- "remote_file.stat.mode == '0755'"
test_tomcat_conf_dir: "/etc/tomcat"
test_tomcat_context_xml_file: "{{ test_tomcat_conf_dir }}/context.xml"
$ molecule verify, , . :
- name: "tomcat - copy dynamic tomcat server config files"
template:
src: "{{ tomcat_context_xml_file }}"
dest: "{{ tomcat_conf_dir }}"
tomcat_conf_dir: "/etc/tomcat"
tomcat_context_xml_file: "tomcat/context.xml"
$ molecule converge, $ molecule verify. , .
, , $ molecule test, Molecule test_sequence. .
Kesimpulannya, menurut saya, ini adalah pendekatan yang tepat untuk mengembangkan tes Molekul untuk peran yang mungkin. Kode infrastruktur harus diuji sebelum penerapan di lingkungan produksi untuk menghindari kejutan yang tidak menyenangkan. Tutorial ini adalah demonstrasi sederhana tentang bagaimana Anda dapat menguji Ansible with Molecule menggunakan Ansible Verifier. Dengan demikian, tidak perlu mempelajari bahasa pemrograman lain seperti Python, Ruby atau Go.