├── .gitignore ├── Readme.md ├── bad-practice ├── Readme.md ├── example.yml ├── handlers │ └── y.yml ├── include.yml ├── lineno.yml ├── lots_of_warnings.yml ├── nomatches.yml ├── play.yml ├── roles │ ├── bobbins │ │ └── tasks │ │ │ └── main.yml │ ├── hello │ │ └── meta │ │ │ └── main.yml │ └── morecomplex │ │ ├── handlers │ │ └── main.yml │ │ └── tasks │ │ └── main.yml ├── rules │ └── TaskHasTag.py └── tasks │ └── x.yml ├── code-quality ├── Readme.md ├── docker-compose.yml ├── dockerfiles │ ├── scanner.Dockerfile │ ├── sonarqube-init.Dockerfile │ └── sonarqube-init.sh ├── playbooks │ ├── playbook.yml │ ├── roles │ │ └── application │ │ │ ├── README.md │ │ │ ├── defaults │ │ │ └── main.yml │ │ │ ├── handlers │ │ │ └── main.yml │ │ │ ├── meta │ │ │ └── main.yml │ │ │ ├── tasks │ │ │ └── main.yml │ │ │ ├── tests │ │ │ ├── inventory │ │ │ └── test.yml │ │ │ └── vars │ │ │ └── main.yml │ └── sonar-project.properties ├── scanner.yml └── vhosts.conf ├── samples ├── ansible-modules │ ├── Readme.md │ └── slurp.yml ├── conditions │ ├── README.md │ ├── example_conditions_boolean.yml │ ├── example_conditions_default.yml │ ├── example_conditions_defined.yml │ ├── example_conditions_register.yml │ ├── example_conditions_succeeded.yml │ ├── example_conditions_variables.yml │ ├── example_conditions_when-item.yml │ └── example_conditions_when-search.yml ├── filter_plugin │ ├── README.md │ ├── ansible.cfg │ ├── filter │ │ ├── filter_plugin.py │ │ └── filter_plugin.pyc │ └── filter_example.yml ├── filters │ ├── README.md │ ├── formatting.yml │ ├── hash.yml │ ├── ip.yml │ ├── list.yml │ ├── math.yaml │ ├── omit_mandatory_default.yml │ ├── random.yml │ └── theory.yml ├── include │ ├── README.md │ ├── child_play.yml │ ├── example_include.yml │ └── tasks │ │ └── child_task.yml ├── include_vars │ ├── README.md │ ├── example_include-vars.yml │ └── vars │ │ ├── Debian.yml │ │ ├── RedHat.yml │ │ └── test.yml ├── inventory │ ├── README.md │ ├── inventory │ └── inventory_example.yml ├── local_facts │ ├── README.md │ ├── example_local-facts.yml │ └── files │ │ ├── exec_java.fact │ │ ├── ini_example.fact │ │ └── json_example.fact ├── loops │ ├── README.md │ ├── files │ │ ├── first_file │ │ ├── second_file │ │ └── third_file │ ├── iterating-over-result-example.yml │ ├── loop-control.yml │ ├── loop-do-until.yml │ ├── looping-over-fileglobs-example.yml │ ├── looping-over-files-example.yml │ ├── looping-over-hashes-example.yml │ ├── looping-over-integer-sequences-example.yml │ ├── looping-over-inventory.yml │ ├── looping-over-parallel-sets-data-example.yml │ ├── looping-over-subelements-example.yml │ ├── looping-with-register.yml │ ├── loops-with-indexes.yml │ ├── nested-loop-example.yml │ ├── random-choices-example.yml │ └── standart-loop-example.yml ├── modules │ ├── README.md │ ├── custom_modules_examples.yml │ ├── library │ │ ├── bash-module.sh │ │ ├── boilerplate.py │ │ ├── fact-module.py │ │ └── python-module.py │ └── python_module_boilerplate_example.yml ├── order_in_playbook │ ├── README.md │ ├── example_order.yml │ └── roles │ │ └── some_role │ │ ├── defaults │ │ └── main.yml │ │ ├── handlers │ │ └── main.yml │ │ ├── meta │ │ └── main.yml │ │ ├── tasks │ │ └── main.yml │ │ └── vars │ │ └── main.yml ├── plugins │ ├── action │ │ ├── action_plugins │ │ │ ├── echo_action_no_module.py │ │ │ └── echo_action_with_module.py │ │ ├── demo.yml │ │ ├── library │ │ │ ├── echo_action_with_module │ │ │ └── echo_module │ │ └── secretfile │ ├── callback │ │ ├── ansible.cfg │ │ ├── callback_plugins │ │ │ ├── cb_log.py │ │ │ ├── cb_notify.py │ │ │ └── cb_stdout.py │ │ └── demo.yml │ └── connection │ │ ├── README.md │ │ ├── ansible.cfg │ │ ├── connection_plugins │ │ └── docker_plugin.py │ │ └── demo.yml ├── project_structure │ ├── README.md │ ├── common.yml │ ├── dbservers.yml │ ├── filter_plugins │ │ └── some_plugin │ ├── inventories │ │ ├── production │ │ │ ├── group_vars │ │ │ │ ├── all │ │ │ │ ├── atlanta │ │ │ │ └── webservers │ │ │ ├── host_vars │ │ │ │ └── db-bos-1.example.com │ │ │ └── hosts │ │ └── staging │ │ │ ├── group_vars │ │ │ ├── group1 │ │ │ └── group2 │ │ │ ├── host_vars │ │ │ ├── stagehost1 │ │ │ └── stagehost2 │ │ │ └── hosts │ ├── library │ │ └── some_module │ ├── roles │ │ ├── common │ │ │ ├── .travis.yml │ │ │ ├── README.md │ │ │ ├── defaults │ │ │ │ └── main.yml │ │ │ ├── handlers │ │ │ │ └── main.yml │ │ │ ├── meta │ │ │ │ └── main.yml │ │ │ ├── tasks │ │ │ │ └── main.yml │ │ │ ├── tests │ │ │ │ ├── inventory │ │ │ │ └── test.yml │ │ │ └── vars │ │ │ │ └── main.yml │ │ ├── dbserver │ │ │ ├── .travis.yml │ │ │ ├── README.md │ │ │ ├── defaults │ │ │ │ └── main.yml │ │ │ ├── handlers │ │ │ │ └── main.yml │ │ │ ├── meta │ │ │ │ └── main.yml │ │ │ ├── tasks │ │ │ │ └── main.yml │ │ │ ├── tests │ │ │ │ ├── inventory │ │ │ │ └── test.yml │ │ │ └── vars │ │ │ │ └── main.yml │ │ └── webserver │ │ │ ├── .travis.yml │ │ │ ├── README.md │ │ │ ├── defaults │ │ │ └── main.yml │ │ │ ├── handlers │ │ │ └── main.yml │ │ │ ├── meta │ │ │ └── main.yml │ │ │ ├── tasks │ │ │ └── main.yml │ │ │ ├── tests │ │ │ ├── inventory │ │ │ └── test.yml │ │ │ └── vars │ │ │ └── main.yml │ ├── site.yml │ └── webservers.yml ├── registered_vars │ ├── README.md │ └── playbook.yml ├── special-variables │ ├── Readme.md │ ├── roles │ │ └── sample-role │ │ │ └── tasks │ │ │ └── main.yml │ └── variables.yml ├── strategies │ ├── README.md │ ├── inventory │ └── strategy_example.yml ├── templates │ ├── README.md │ ├── templates │ │ ├── virtual-host.conf │ │ └── virtual-host.conf.j2 │ └── vhost.yml ├── variables │ ├── README.md │ ├── host_vars.yml │ ├── inventory │ └── vars_example.yml └── vault │ ├── Readme.md │ ├── resources │ ├── secret-file-for-copy.txt │ ├── secret-file-for-template.txt │ ├── secret-variables.yml │ └── vault-secret-password.txt │ ├── test-secret-copy-1.yml │ ├── test-secret-copy-2.yml │ ├── test-secret-file.yml │ ├── test-secret-template.yml │ └── test-secret-variable.yml └── trainings ├── Readme.md ├── day-1 ├── Makefile ├── Readme.md ├── Vagrantfile ├── ansible.cfg ├── inventory01 ├── inventory02 ├── inventory03 └── tasks │ ├── 11.yml │ ├── 12.yml │ ├── 13.yml │ ├── files │ ├── nginx_home.html │ └── tomcat.service │ └── templates │ └── tomcat.service.j2 ├── day-2 ├── Makefile ├── Readme.md ├── Vagrantfile ├── ansible.cfg ├── inventory └── tasks │ ├── 21.yml │ ├── 22.yml │ ├── 23.yml │ └── roles │ ├── base │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── tests │ │ ├── inventory │ │ └── test.yml │ └── vars │ │ └── main.yml │ ├── java │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── tests │ │ ├── inventory │ │ └── test.yml │ └── vars │ │ └── main.yml │ ├── nginx │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── files │ │ └── nginx_home.html │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── tests │ │ ├── inventory │ │ └── test.yml │ └── vars │ │ └── main.yml │ └── tomcat │ ├── README.md │ ├── defaults │ └── main.yml │ ├── handlers │ └── main.yml │ ├── meta │ └── main.yml │ ├── tasks │ └── main.yml │ ├── templates │ ├── context.xml.j2 │ ├── tomcat-users.xml.j2 │ └── tomcat.service.j2 │ ├── tests │ ├── inventory │ └── test.yml │ └── vars │ └── main.yml ├── day-3 ├── Makefile ├── Readme.md ├── Vagrantfile ├── ansible.cfg ├── inventory ├── sample.war └── tasks │ ├── corporate_emails │ ├── corporate_email.yml │ ├── filter_plugins │ │ └── filters.py │ └── output.txt │ ├── custom_modules │ ├── library │ │ ├── custom_module_args_bash.sh │ │ ├── custom_module_args_python.py │ │ ├── custom_module_bash.sh │ │ ├── custom_module_python.py │ │ ├── deploy_war.py │ │ └── vagrant_box.py │ ├── test.yml │ └── testing_modules.yml │ ├── inventory_script │ ├── Readme.md │ ├── test-vagrant-inventory.yml │ └── vagrant_inventory.py │ ├── mongodb_selector_filter │ ├── filter_plugins │ │ └── filters.py │ └── mongodb_url_select.yml │ └── vagrant_management │ ├── deployment.json │ └── vagrant.yml ├── day-4 ├── Makefile ├── Readme.md ├── Vagrantfile ├── ansible.cfg └── tasks │ ├── blocks │ └── rescue.yml │ ├── callback │ ├── ansible.cfg │ ├── callback-test.yml │ └── callback_plugins │ │ └── demo.py │ ├── tags │ ├── deployment.json │ ├── sample.war │ └── vagrant.yml │ └── templates │ ├── templates │ ├── template-example-0.j2 │ ├── template-example-1.j2 │ ├── template-example-2.j2 │ └── template-example-3.j2 │ └── testing_templates.yml └── day-5 ├── Readme.md ├── Vagrantfile ├── ansible.cfg ├── inventory └── tasks ├── packer ├── Readme.md ├── example.json ├── provision.yml └── roles │ └── nginx │ ├── README.md │ ├── defaults │ └── main.yml │ ├── handlers │ └── main.yml │ ├── meta │ └── main.yml │ ├── tasks │ ├── lb.yml │ ├── main.yml │ └── node.yml │ ├── templates │ ├── index.html.j2 │ └── nginx-lb.conf.j2 │ ├── tests │ ├── inventory │ └── test.yml │ └── vars │ └── main.yml ├── pull ├── ansible-pull-configure.yml ├── docker-compose.yml ├── local.yml ├── roles │ └── nginx │ │ ├── README.md │ │ ├── defaults │ │ └── main.yml │ │ ├── handlers │ │ └── main.yml │ │ ├── meta │ │ └── main.yml │ │ ├── tasks │ │ ├── lb.yml │ │ ├── main.yml │ │ └── node.yml │ │ ├── templates │ │ ├── index.html.j2 │ │ └── nginx-lb.conf.j2 │ │ ├── tests │ │ ├── inventory │ │ └── test.yml │ │ └── vars │ │ └── main.yml └── templates │ └── etc_logrotate.d_ansible-pull.j2 └── vault ├── Readme.md ├── a_password_file ├── b_password_file └── test.yml /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.retry 3 | .vagrant 4 | .sonar 5 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/Readme.md -------------------------------------------------------------------------------- /bad-practice/Readme.md: -------------------------------------------------------------------------------- 1 | ## Checking Ansible playbooks with Ansible Lint 2 | 3 | ### Ansible Lint: 4 | - [ansible-lint on github](https://github.com/ansible/ansible-lint) 5 | - [ansible-lint on docs.ansible.com](https://docs.ansible.com/ansible-lint/) 6 | - [default rules description](https://docs.ansible.com/ansible-lint/rules/default_rules.html) 7 | 8 | ### Usage: 9 | ```bash 10 | $ docker run -v $(pwd):/opt/work sbeliakou/ansible-check:3.5.1 example.yml 11 | example.yml:9: 12 | 7: tasks: 13 | 8: - command: echo hello world 14 | -> 9: 15 | 10: - name: trailing whitespace 16 | 11: command: echo do nothing 17 | 18 | 19 | [E301] Commands should not change things if nothing needs doing 20 | Commands should either read information (and thus set changed_when) or not do something if it has already been done (using creates/removes) or only do it if another check has a particular result (when) 21 | 22 | [E502] All tasks should be named 23 | All tasks should have a distinct name for readability and for --start-at-task to work 24 | ... 25 | ``` 26 | 27 | ```bash 28 | $ alias ansible-check='docker run -v $(pwd):/opt/work sbeliakou/ansible-check:3.5.1' 29 | $ ansible-check play.yml 30 | play.yml:5: 31 | 3: tasks: 32 | 4: - name: a bad play 33 | -> 5: shell: service blah restart 34 | 6: sudo: yes 35 | 36 | 37 | [E103] Deprecated sudo 38 | Instead of sudo/sudo_user, use become/become_user. 39 | 40 | [E301] Commands should not change things if nothing needs doing 41 | Commands should either read information (and thus set changed_when) or not do something if it has already been done (using creates/removes) or only do it if another check has a particular result (when) 42 | 43 | [E303] service used in place of service module 44 | Executing a command when there is an Ansible module is generally a bad idea 45 | 46 | [E305] Use shell only when shell functionality is required 47 | Shell should only be used when piping, redirecting or chaining commands (and Ansible would be preferred for some of those!) 48 | 49 | ``` 50 | -------------------------------------------------------------------------------- /bad-practice/example.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: webservers 3 | 4 | vars: 5 | oldskool: "1.2.3" 6 | bracket: "and close bracket" 7 | 8 | tasks: 9 | - command: echo hello world 10 | 11 | - name: trailing whitespace 12 | command: echo do nothing 13 | 14 | - name: git check 15 | git: a=b c=d 16 | 17 | - name: git check 2 18 | git: version=HEAD c=d 19 | 20 | - name: git check 3 21 | git: version=a1b2c3d4 repo=xyz bobbins=d 22 | 23 | - name: executing git through command 24 | shell: git clone blah 25 | 26 | - name: executing git through command 27 | shell: chdir=bobbins creates=whatever /usr/bin/git clone blah 28 | 29 | - name: using git module 30 | action: git repo=blah 31 | 32 | - name: passing git as an argument to another task 33 | action: debug msg="{{item}}" 34 | with_items: 35 | - git 36 | - bobbins 37 | 38 | - name: yum latest 39 | yum: state=latest name=httpd 40 | 41 | - debug: msg="task without a name" 42 | 43 | - name: apt latest 44 | apt: state=latest name=apache2 45 | 46 | - name: always run 47 | debug: msg="always_run is deprecated" 48 | always_run: true 49 | -------------------------------------------------------------------------------- /bad-practice/handlers/y.yml: -------------------------------------------------------------------------------- 1 | - name: funny handler 2 | action: service name=funny state=started force=true 3 | -------------------------------------------------------------------------------- /bad-practice/include.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: bobbins 3 | 4 | 5 | pre_tasks: 6 | - include: tasks/x.yml 7 | 8 | roles: 9 | - hello 10 | - { role: morecomplex, t: z } 11 | 12 | tasks: 13 | - include: tasks/x.yml 14 | - include: tasks/x.yml y=z 15 | 16 | handlers: 17 | - include: handlers/y.yml 18 | 19 | - include: play.yml 20 | 21 | -------------------------------------------------------------------------------- /bad-practice/lineno.yml: -------------------------------------------------------------------------------- 1 | - tasks: 2 | - git: repo=hello 3 | -------------------------------------------------------------------------------- /bad-practice/nomatches.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: whatever 3 | 4 | tasks: 5 | - name: hello world 6 | action: debug msg="Hello!" 7 | 8 | - name: this should be fine too 9 | action: file state=touch dest=./wherever 10 | -------------------------------------------------------------------------------- /bad-practice/play.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: bobbins 3 | 4 | tasks: 5 | - name: a bad play 6 | shell: service blah restart 7 | sudo: yes 8 | -------------------------------------------------------------------------------- /bad-practice/roles/bobbins/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: test tasks 3 | action: git a=b c=d 4 | 5 | -------------------------------------------------------------------------------- /bad-practice/roles/hello/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: 3 | - role: bobbins 4 | -------------------------------------------------------------------------------- /bad-practice/roles/morecomplex/handlers/main.yml: -------------------------------------------------------------------------------- 1 | - name: restart service using command 2 | command: service bar restart 3 | -------------------------------------------------------------------------------- /bad-practice/roles/morecomplex/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: test bad command 2 | action: command mkdir blah 3 | 4 | - name: test bad command v2 5 | command: mkdir blah 6 | 7 | - name: test bad local command 8 | local_action: shell touch foo 9 | -------------------------------------------------------------------------------- /bad-practice/rules/TaskHasTag.py: -------------------------------------------------------------------------------- 1 | from ansiblelint import AnsibleLintRule 2 | 3 | 4 | class TaskHasTag(AnsibleLintRule): 5 | id = 'EXAMPLE001' 6 | shortdesc = 'Tasks must have tag' 7 | description = 'Tasks must have tag' 8 | tags = ['productivity', 'tags'] 9 | 10 | def matchtask(self, file, task): 11 | # The meta files don't have tags 12 | if file['type'] in ["meta", "playbooks"]: 13 | return False 14 | 15 | if isinstance(task, str): 16 | return False 17 | 18 | # If the task include another task or make the playbook fail 19 | # Don't force to have a tag 20 | if not set(task.keys()).isdisjoint(['include', 'fail']): 21 | return False 22 | 23 | if not set(task.keys()).isdisjoint(['include_tasks', 'fail']): 24 | return False 25 | 26 | if not set(task.keys()).isdisjoint(['import_tasks', 'fail']): 27 | return False 28 | 29 | # Task should have tags 30 | if 'tags' not in task: 31 | return True 32 | 33 | return False 34 | -------------------------------------------------------------------------------- /bad-practice/tasks/x.yml: -------------------------------------------------------------------------------- 1 | - name: test include 2 | action: funny value=clown 3 | args: 4 | key: value 5 | -------------------------------------------------------------------------------- /code-quality/Readme.md: -------------------------------------------------------------------------------- 1 | ## Roll Out SonarQube 2 | ``` 3 | docker-compose up -d sonarqube db 4 | ``` 5 | 6 | ## Scan 7 | ``` 8 | docker-compose up scanner 9 | ``` -------------------------------------------------------------------------------- /code-quality/dockerfiles/scanner.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:2.7 2 | 3 | RUN pip install ansible-lint==3.4.15 4 | 5 | RUN apt-get update && \ 6 | apt install -y default-jre && \ 7 | java -version 8 | 9 | RUN apt-get install -y unzip && \ 10 | wget -q -nc http://repo1.maven.org/maven2/org/codehaus/sonar/runner/sonar-runner-dist/2.4/sonar-runner-dist-2.4.zip && \ 11 | unzip sonar-runner-dist-2.4.zip && \ 12 | chmod a+x /sonar-runner-2.4/bin/* && \ 13 | rm -f sonar-runner-dist-2.4.zip 14 | 15 | ENV PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/sonar-runner-2.4/bin 16 | 17 | ENTRYPOINT /sonar-runner-2.4/bin/sonar-runner -------------------------------------------------------------------------------- /code-quality/dockerfiles/sonarqube-init.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.8 2 | 3 | RUN apk add --no-cache curl bash jq && rm -rf /var/cache/apk/* 4 | 5 | COPY sonarqube-init.sh / 6 | 7 | ENTRYPOINT ["/bin/bash", "/sonarqube-init.sh"] -------------------------------------------------------------------------------- /code-quality/dockerfiles/sonarqube-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | mkdir -p /opt/sonarqube/extensions/plugins 5 | mkdir -p /opt/sonarqube/extensions/downloads 6 | chown -R 999: /opt/sonarqube/extensions/* 7 | ls -la /opt/sonarqube/extensions/ 8 | 9 | cd /opt/sonarqube/extensions/plugins 10 | 11 | echo Downloading plugins 12 | wget -q -nc https://github.com/sbaudoin/sonar-yaml/releases/download/v1.3.0/sonar-yaml-plugin-1.3.0.jar 13 | stat -c '>> %s (%u:%g) %n' $(pwd)/sonar-yaml-plugin-1.3.0.jar 14 | 15 | wget -q -nc https://github.com/sbaudoin/sonar-ansible/releases/download/v2.0.0/sonar-ansible-plugin-2.0.0.jar 16 | stat -c '>> %s (%u:%g) %n' $(pwd)/sonar-ansible-plugin-2.0.0.jar 17 | 18 | wget -q -nc https://github.com/sbaudoin/sonar-ansible/releases/download/v2.0.0/sonar-ansible-extras-plugin-2.0.0.jar 19 | stat -c '>> %s (%u:%g) %n' $(pwd)/sonar-ansible-extras-plugin-2.0.0.jar 20 | 21 | until curl --connect-timeout 1 -s -u admin:admin --output /dev/null -X POST -f http://sonarqube:9000/api/system/info 22 | do 23 | echo $? waiting for sonar is ready 24 | sleep 1 25 | done 26 | 27 | curl -u admin:admin -X POST 'http://sonarqube:9000/api/qualityprofiles/create?language=yaml&name=Ansible' 28 | key=$(curl -s -u admin:admin -X POST 'http://sonarqube:9000/api/qualityprofiles/search?qualityProfile=Ansible' | jq -r '.profiles[].key') 29 | curl -u admin:admin -X POST "http://sonarqube:9000/api/qualityprofiles/activate_rules?tags=ansible&targetKey=${key}" 30 | curl -u admin:admin -X POST "http://sonarqube:9000/api/qualityprofiles/set_default?key=${key}" 31 | curl -u admin:admin -X POST 'http://sonarqube:9000/api/qualitygates/create?name=Ansible' -------------------------------------------------------------------------------- /code-quality/playbooks/playbook.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | 3 | vars: 4 | vault_access_token_path: "/infrastructure/teams/vault-access-token" 5 | vault_access_token: "{{ lookup('hashivault', vault_access_token_path, 'value') }}" 6 | 7 | tasks: 8 | - shell: echo hello world 9 | always_run: yes 10 | sudo: yes 11 | sudo_user: admin 12 | 13 | roles: 14 | - application -------------------------------------------------------------------------------- /code-quality/playbooks/roles/application/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /code-quality/playbooks/roles/application/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for application -------------------------------------------------------------------------------- /code-quality/playbooks/roles/application/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for application -------------------------------------------------------------------------------- /code-quality/playbooks/roles/application/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: your name 3 | description: your description 4 | company: your company (optional) 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 2.4 20 | 21 | # If this a Container Enabled role, provide the minimum Ansible Container version. 22 | # min_ansible_container_version: 23 | 24 | # Optionally specify the branch Galaxy will use when accessing the GitHub 25 | # repo for this role. During role install, if no tags are available, 26 | # Galaxy will use this branch. During import Galaxy will access files on 27 | # this branch. If Travis integration is configured, only notifications for this 28 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 29 | # (usually master) will be used. 30 | #github_branch: 31 | 32 | # 33 | # Provide a list of supported platforms, and for each platform a list of versions. 34 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 35 | # To view available platforms and versions (or releases), visit: 36 | # https://galaxy.ansible.com/api/v1/platforms/ 37 | # 38 | # platforms: 39 | # - name: Fedora 40 | # versions: 41 | # - all 42 | # - 25 43 | # - name: SomePlatform 44 | # versions: 45 | # - all 46 | # - 1.0 47 | # - 7 48 | # - 99.99 49 | 50 | galaxy_tags: [] 51 | # List tags for your role here, one per line. A tag is a keyword that describes 52 | # and categorizes the role. Users find roles by searching for tags. Be sure to 53 | # remove the '[]' above, if you add tags to this list. 54 | # 55 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 56 | # Maximum 20 tags per role. 57 | 58 | dependencies: [] 59 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 60 | # if you add dependencies to this list. -------------------------------------------------------------------------------- /code-quality/playbooks/roles/application/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - shell: echo hello world 2 | always_run: yes 3 | sudo: yes 4 | sudo_user: admin -------------------------------------------------------------------------------- /code-quality/playbooks/roles/application/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /code-quality/playbooks/roles/application/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - application -------------------------------------------------------------------------------- /code-quality/playbooks/roles/application/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for application -------------------------------------------------------------------------------- /code-quality/playbooks/sonar-project.properties: -------------------------------------------------------------------------------- 1 | # must be unique in a given SonarQube instance 2 | sonar.projectKey=sbeliakou:hello-playbook 3 | # this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1. 4 | sonar.projectName=Testing Hello World Playbook 5 | sonar.projectVersion=1.0 6 | 7 | # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. 8 | # This property is optional if sonar.modules is set. 9 | sonar.sources=. 10 | 11 | # Encoding of the source code. Default is default system encoding 12 | #sonar.sourceEncoding=UTF-8 -------------------------------------------------------------------------------- /code-quality/scanner.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | 3 | services: 4 | scanner: 5 | build: 6 | dockerfile: scanner.Dockerfile 7 | context: dockerfiles/ 8 | volumes: 9 | - ./playbooks:${PWD}/playbooks 10 | - scanner_cache:/root/.sonar 11 | working_dir: ${PWD}/playbooks 12 | entrypoint: sonar-runner -Dsonar.host.url=http://sonar-ci.playpit.by 13 | 14 | volumes: 15 | scanner_cache: -------------------------------------------------------------------------------- /code-quality/vhosts.conf: -------------------------------------------------------------------------------- 1 | upstream jenkins { 2 | server jenkins:8080; 3 | } 4 | 5 | upstream sonar { 6 | server sonarqube:9000; 7 | } 8 | 9 | server { 10 | listen 80; 11 | server_name sonar.playpit.net; 12 | 13 | location / { 14 | proxy_pass http://sonar; 15 | client_max_body_size 2G; 16 | proxy_buffering off; 17 | proxy_redirect off; 18 | proxy_set_header X-Real-IP $remote_addr; 19 | proxy_set_header X-Scheme $scheme; 20 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 21 | proxy_set_header Host $host; 22 | # proxy_set_header X-Forwarded-Proto https; 23 | proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; 24 | } 25 | } 26 | 27 | server { 28 | listen 80; 29 | server_name jenkins.playpit.net; 30 | 31 | location / { 32 | proxy_pass http://jenkins; 33 | client_max_body_size 2G; 34 | proxy_buffering off; 35 | proxy_redirect off; 36 | proxy_set_header X-Real-IP $remote_addr; 37 | proxy_set_header X-Scheme $scheme; 38 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 39 | proxy_set_header Host $host; 40 | # proxy_set_header X-Forwarded-Proto https; 41 | proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; 42 | } 43 | 44 | 45 | } -------------------------------------------------------------------------------- /samples/ansible-modules/Readme.md: -------------------------------------------------------------------------------- 1 | ## Ansible Modules 2 | 3 | - [slurp](https://docs.ansible.com/ansible/latest/modules/slurp_module.html) - This module works like [fetch]. It is used for fetching a base64- encoded blob containing the data in a remote file. This module is also supported for Windows targets. 4 | -------------------------------------------------------------------------------- /samples/ansible-modules/slurp.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: no 3 | 4 | tasks: 5 | - copy: 6 | content: | 7 | token: "123456789.abcdef" 8 | something_else: "abc_abc_def_def" 9 | dest: /tmp/token 10 | 11 | - slurp: src=/tmp/token 12 | register: vars_from_file 13 | 14 | - set_fact: "{{ item.key }}={{ item.value }}" 15 | with_dict: "{{ vars_from_file['content'] | b64decode | from_yaml }}" 16 | 17 | - debug: var=token 18 | - debug: var=something_else 19 | -------------------------------------------------------------------------------- /samples/conditions/example_conditions_boolean.yml: -------------------------------------------------------------------------------- 1 | - name: Execution of a task based on a variable’s boolean value 2 | hosts: localhost 3 | 4 | vars: 5 | epic: true 6 | 7 | tasks: 8 | - name: Step when epic is True 9 | debug: 10 | msg: "This certainly is epic!" 11 | when: epic 12 | 13 | - name: Step when epic is not True 14 | debug: 15 | msg: "This certainly isn't epic!" 16 | when: not epic 17 | 18 | -------------------------------------------------------------------------------- /samples/conditions/example_conditions_default.yml: -------------------------------------------------------------------------------- 1 | - name: Using when + default filter 2 | hosts: localhost 3 | 4 | vars: 5 | mylist: [ 0, 2, 4, 6, 8, 10 ] 6 | tasks: 7 | 8 | - name: When list does not exist step is using default. Default is empty --> SKIP it 9 | debug: msg="{{ item }}" 10 | with_items: "{{ list|default([]) }}" 11 | when: item > 5 12 | 13 | - name: When mylist does not exist step is using default. Mylist exists --> DO it 14 | debug: msg="{{ item }}" 15 | with_items: "{{ mylist|default([]) }}" 16 | when: item > 5 17 | 18 | -------------------------------------------------------------------------------- /samples/conditions/example_conditions_defined.yml: -------------------------------------------------------------------------------- 1 | - name: Check registered variable for emptiness 2 | hosts: localhost 3 | 4 | vars: 5 | foo: power 6 | tasks: 7 | 8 | - debug: msg="I've got a '{{ foo }}' and am not afraid to use it!" 9 | when: foo is defined 10 | 11 | - fail: msg="Bailing out. this play requires 'bar'" 12 | when: bar is undefined 13 | 14 | -------------------------------------------------------------------------------- /samples/conditions/example_conditions_register.yml: -------------------------------------------------------------------------------- 1 | - name: Check registered variable for emptiness 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Ensure directory exists 6 | file: 7 | path: mydir 8 | state: directory 9 | mode: 0755 10 | 11 | - name: list contents of directory 12 | command: ls mydir 13 | register: contents 14 | 15 | - name: check contents for emptiness 16 | debug: msg="Directory is empty" 17 | when: contents.stdout == "" 18 | 19 | -------------------------------------------------------------------------------- /samples/conditions/example_conditions_succeeded.yml: -------------------------------------------------------------------------------- 1 | - name: Statement based on the result of registering 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Echo something 6 | debug: msg="Hello world!" 7 | register: result 8 | 9 | - name: Do it if the result of the first step was failed 10 | debug: msg="Ooops.." 11 | when: result|failed 12 | 13 | - name: Do it if the result of the first step was succeeded 14 | debug: msg="Everything is OK" 15 | when: result|succeeded 16 | 17 | - name: Do it if the result of the first step was skipped 18 | debug: msg="Goodbye" 19 | when: result|skipped 20 | 21 | -------------------------------------------------------------------------------- /samples/conditions/example_conditions_variables.yml: -------------------------------------------------------------------------------- 1 | - name: Statement is based on variables 2 | hosts: localhost 3 | 4 | tasks: 5 | 6 | - name: "Echo something on Debian systems" 7 | debug: msg="OS is Debian" 8 | when: 9 | - ansible_distribution == "Debian" 10 | 11 | - name: "Echo something on CentOS 7 systems" 12 | debug: msg="OS is CentOS 7" 13 | when: 14 | - ansible_distribution == "CentOS" 15 | - ansible_distribution_major_version == "7" 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/conditions/example_conditions_when-item.yml: -------------------------------------------------------------------------------- 1 | - name: Combining when with with_items 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: statement WHEN is processed separately for each item 6 | debug: 7 | msg: "{{ item }} is > 5 " 8 | with_items: [ 0, 2, 4, 6, 8, 10 ] 9 | when: item > 5 10 | -------------------------------------------------------------------------------- /samples/conditions/example_conditions_when-search.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | 4 | vars: 5 | myvar1: "asdfasdfasdfAAAasdfasdfasdf" 6 | myvar2: "qweqwerqweqweqqweqweqweqweq" 7 | 8 | tasks: 9 | - debug: msg="Variable contains 'AAA' -> '{{ item }}'" 10 | when: item | search('AAA') 11 | with_items: 12 | - '{{ myvar1 }}' 13 | - '{{ myvar2 }}' 14 | -------------------------------------------------------------------------------- /samples/filter_plugin/README.md: -------------------------------------------------------------------------------- 1 | # Filter plugin 2 | 3 | [http://docs.ansible.com/ansible/dev_guide/developing_plugins.html#filter-plugins] 4 | 5 | Example contents: 6 | - [demo playbook](filter_example.yml) 7 | - [ansible config](ansible.cfg) 8 | - [filter plugin](filter/filter_plugin.py) 9 | 10 | Usage: 11 | ```sh 12 | $ ansible-playbook filter_example.yml 13 | ``` 14 | 15 | Output: 16 | ```sh 17 | PLAY *************************************************************************** 18 | 19 | TASK [setup] ******************************************************************* 20 | ok: [localhost] 21 | 22 | TASK [First filter usage example] ********************************************** 23 | ok: [localhost] => { 24 | "msg": "test processed with one_filter" 25 | } 26 | 27 | TASK [Second filter usage example] ********************************************* 28 | ok: [localhost] => { 29 | "msg": "one - two - three processed with another_filter" 30 | } 31 | 32 | PLAY RECAP ********************************************************************* 33 | localhost : ok=3 changed=0 unreachable=0 failed=0 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /samples/filter_plugin/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | 3 | # set plugin path directories here, separate with colons 4 | filter_plugins = filter 5 | -------------------------------------------------------------------------------- /samples/filter_plugin/filter/filter_plugin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | class FilterModule(object): 3 | def filters(self): 4 | return { 5 | 'one_filter': self.a_filter, 6 | 'another_filter': self.b_filter 7 | } 8 | 9 | def a_filter(self, a_variable): 10 | a_new_variable = a_variable + ' processed with one_filter' 11 | return a_new_variable 12 | 13 | def b_filter(self, a_variable, another_variable, yet_another_variable): 14 | a_new_variable = a_variable + ' - ' + another_variable + ' - ' + yet_another_variable + ' processed with another_filter' 15 | return a_new_variable -------------------------------------------------------------------------------- /samples/filter_plugin/filter/filter_plugin.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/filter_plugin/filter/filter_plugin.pyc -------------------------------------------------------------------------------- /samples/filter_plugin/filter_example.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | connection: local 4 | tasks: 5 | - name: First filter usage example 6 | debug: 7 | msg: "{{ 'test' | one_filter() }}" 8 | - name: Second filter usage example 9 | debug: 10 | msg: "{{ 'one' | another_filter('two','three') }}" 11 | 12 | 13 | -------------------------------------------------------------------------------- /samples/filters/formatting.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | tasks: 4 | - shell: cat filters/formatting.yml 5 | register: result 6 | - set_fact: from_yaml="{{ result.stdout | from_yaml }}" 7 | - name: "Shell output of the current playbook" 8 | debug: var=result.stdout 9 | - name: "YAML-formatted output of the current playbook" 10 | debug: var=from_yaml 11 | -------------------------------------------------------------------------------- /samples/filters/hash.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | tasks: 4 | - name: "Sha1 hash of a string 'test1'" 5 | debug: 6 | msg: "{{ 'test1'|hash('sha1') }}" 7 | - name: "Md5 hash of a string 'test1'" 8 | debug: 9 | msg: "{{ 'test1'|hash('md5') }}" 10 | - name: "Checksum of a string 'test2'" 11 | debug: 12 | msg: "{{ 'test2'|checksum }}" 13 | - name: "Sha512 password hash (random salt)" 14 | debug: 15 | msg: "{{ 'passwordsaresecret'|password_hash('sha512') }}" 16 | -------------------------------------------------------------------------------- /samples/filters/ip.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | vars: 4 | ip1: '192.168.0.1' 5 | ip2: '192.168.257.1' 6 | tasks: 7 | - name: "Test if a string '192.168.0.1' is a valid IP address" 8 | debug: 9 | msg: "{{ ip1 | ipaddr }}" 10 | - name: "Test if a string '192.168.257.1' is a valid IP address" 11 | debug: 12 | msg: "{{ ip2 | ipaddr }}" 13 | - name: "Test if a string '192.168.0.1' is a valid IPv6 address" 14 | debug: 15 | msg: "{{ ip1 | ipv6 }}" 16 | - name: "Get the IP address itself from a CIDR '192.0.2.1/24'" 17 | debug: 18 | msg: "{{ '192.0.2.1/24' | ipaddr('address') }}" 19 | -------------------------------------------------------------------------------- /samples/filters/list.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | vars: 4 | list: [1,2,3,4,5] 5 | tasks: 6 | - name: "Min value of the list [1,2,3,4,5]" 7 | debug: 8 | msg: "{{ list | min }}" 9 | - name: "Max value of the list [1,2,3,4,5]" 10 | debug: 11 | msg: "{{ list | max }}" 12 | - name: "Random list from the list [1,2,3,4,5]" 13 | debug: 14 | msg: "{{ list | shuffle }}" 15 | -------------------------------------------------------------------------------- /samples/filters/math.yaml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | vars: 4 | myvar: 4 5 | tasks: 6 | - name: "The power of 4" 7 | debug: 8 | msg: "{{ myvar | pow(2) }}" 9 | - name: "The square root of 4" 10 | debug: 11 | msg: "{{ myvar | root }}" 12 | -------------------------------------------------------------------------------- /samples/filters/omit_mandatory_default.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | vars: 4 | myvar: defined 5 | tasks: 6 | - name: example of default filter 7 | debug: msg="myvar value is {{ myvar | default('default') }}" 8 | 9 | - hosts: localhost 10 | connection: local 11 | tasks: 12 | - name: example of default filter 13 | debug: msg="myvar value is {{ myvar | default('default') }}" 14 | 15 | - hosts: localhost 16 | connection: local 17 | tasks: 18 | - name: touch files with an optional mode 19 | file: dest={{item.path}} state=touch mode={{item.mode|default(omit)}} 20 | with_items: 21 | - path: /tmp/foo 22 | - path: /tmp/bar 23 | - path: /tmp/baz 24 | mode: "0444" 25 | 26 | - hosts: localhost 27 | connection: local 28 | tasks: 29 | - name: touch files with a mandatory mode 30 | file: dest={{item.path}} state=touch mode={{item.mode|mandatory}} 31 | with_items: 32 | - path: /tmp/foo 33 | - path: /tmp/bar 34 | - path: /tmp/baz 35 | mode: "0444" 36 | -------------------------------------------------------------------------------- /samples/filters/random.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | vars: 4 | list: [1,2,1,3,1] 5 | tasks: 6 | - name: "A random number from list [1,2,1,3,1]" 7 | debug: 8 | msg: "{{ list | random }}" 9 | - name: "A random number from 0 to 100 but in steps of 10" 10 | debug: 11 | msg: "{{ 100 | random(step=10) }}" 12 | - name: "A random number from 1 to 100 but in steps of 10" 13 | debug: 14 | msg: "{{ 100 | random(1,10) }}" 15 | -------------------------------------------------------------------------------- /samples/filters/theory.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | vars: 4 | list1: [1,2,1,3,1] 5 | list2: [4,5,4,6,1] 6 | tasks: 7 | - name: "A unique set from a list [1,2,1,3,1]" 8 | debug: 9 | msg: "{{ list1 | unique }}" 10 | - name: "A union of list [1,2,1,3,1] and list [4,5,4,6,1]" 11 | debug: 12 | msg: "{{ list1 | union(list2) }}" 13 | - name: "An intersection of list [1,2,1,3,1] and list [4,5,4,6,1]" 14 | debug: 15 | msg: "{{ list1 | intersect(list2) }}" 16 | - name: "A difference between list [1,2,1,3,1] and list [4,5,4,6,1]" 17 | debug: 18 | msg: "{{ list1 | difference(list2) }}" 19 | - name: "A symmetric difference between list [1,2,1,3,1] and list [4,5,4,6,1]" 20 | debug: 21 | msg: "{{ list1 | symmetric_difference(list2) }}" 22 | -------------------------------------------------------------------------------- /samples/include/README.md: -------------------------------------------------------------------------------- 1 | # Ansible 'include play and task' example 2 | 3 | ## Resources: 4 | 5 | - [Ansible Docs](http://docs.ansible.com/ansible/playbooks_roles.html#task-versus-play-includes) 6 | - [Demo Playbook](example_include.yml) 7 | 8 | ## Examples: 9 | 10 | ```sh 11 | $ ansible-playbook example_include.yml -c local 12 | ``` 13 | 14 | **Output:** 15 | 16 | ```sh 17 | 18 | PLAY [Example of including a play and a task] ***************************** 19 | 20 | TASK [Gathering Facts] **************************************************** 21 | ok: [localhost] 22 | 23 | TASK [main task] ********************************************************** 24 | ok: [localhost] => { 25 | "msg": "It is a main task" 26 | } 27 | 28 | TASK [child task] ********************************************************* 29 | ok: [localhost] => { 30 | "msg": "It is a child task" 31 | } 32 | 33 | PLAY [Child play] ********************************************************* 34 | 35 | TASK [Gathering Facts] **************************************************** 36 | ok: [localhost] 37 | 38 | TASK [task of child_play] ************************************************* 39 | ok: [localhost] => { 40 | "msg": "It is a task of a child play" 41 | } 42 | 43 | PLAY RECAP **************************************************************** 44 | localhost : ok=5 changed=0 unreachable=0 failed=0 45 | 46 | ``` 47 | 48 | -------------------------------------------------------------------------------- /samples/include/child_play.yml: -------------------------------------------------------------------------------- 1 | - name: Child play 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: task of child_play 6 | debug: 7 | msg: "It is a task of a child play" 8 | -------------------------------------------------------------------------------- /samples/include/example_include.yml: -------------------------------------------------------------------------------- 1 | - name: Example of including a play and a task 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: main task 6 | debug: 7 | msg: "It is a main task" 8 | 9 | - include: tasks/child_task.yml 10 | 11 | - include: child_play.yml 12 | -------------------------------------------------------------------------------- /samples/include/tasks/child_task.yml: -------------------------------------------------------------------------------- 1 | - name: child task 2 | debug: 3 | msg: "It is a child task" 4 | 5 | -------------------------------------------------------------------------------- /samples/include_vars/README.md: -------------------------------------------------------------------------------- 1 | # Ansible 'include vars' example 2 | 3 | ## Resources: 4 | 5 | - [Ansible Docs](http://docs.ansible.com/ansible/include_vars_module.html) 6 | - [Demo Playbook](example_include-vars.yml) 7 | 8 | ## Examples: 9 | 10 | ```sh 11 | $ ansible-playbook example_include-vars.yml -c local 12 | ``` 13 | 14 | **Output:** 15 | 16 | ```sh 17 | 18 | PLAY [Including vars] ************************************************************************ 19 | 20 | TASK [Gathering Facts] *********************************************************************** 21 | ok: [localhost] 22 | 23 | TASK [Include vars of test.yml into the 'var_test' variable.] ******************************** 24 | ok: [localhost] 25 | 26 | TASK [Display value of 'message' variable] *************************************************** 27 | ok: [localhost] => { 28 | "msg": "Hello!" 29 | } 30 | 31 | TASK [Load a variable file based on the OS type, or a default if not found.] ***************** 32 | ok: [localhost] => (item=/root/ansible/examples/ansible-examples/include_vars/vars/RedHat.yml) 33 | 34 | TASK [Display value of 'foo' variable] ******************************************************* 35 | ok: [localhost] => { 36 | "msg": "foo = 111" 37 | } 38 | 39 | PLAY RECAP *********************************************************************************** 40 | localhost : ok=5 changed=0 unreachable=0 failed=0 41 | 42 | ``` 43 | 44 | -------------------------------------------------------------------------------- /samples/include_vars/example_include-vars.yml: -------------------------------------------------------------------------------- 1 | - name: Including vars 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Include vars of test.yml into the 'var_test' variable. 6 | include_vars: 7 | file: test.yml 8 | name: var_test 9 | 10 | - name: Display value of 'message' variable 11 | debug: 12 | msg: "{{ var_test.message }}" 13 | 14 | 15 | - name: Load a variable file based on the OS type, or a default if not found. 16 | include_vars: "{{ item }}" 17 | with_first_found: 18 | - "{{ ansible_distribution }}.yml" 19 | - "{{ ansible_os_family }}.yml" 20 | - "default.yml" 21 | 22 | - name: Display value of 'foo' variable 23 | debug: 24 | msg: "foo = {{ foo }}" 25 | -------------------------------------------------------------------------------- /samples/include_vars/vars/Debian.yml: -------------------------------------------------------------------------------- 1 | foo: 888 2 | bar: 999 3 | 4 | -------------------------------------------------------------------------------- /samples/include_vars/vars/RedHat.yml: -------------------------------------------------------------------------------- 1 | foo: 111 2 | bar: 222 3 | -------------------------------------------------------------------------------- /samples/include_vars/vars/test.yml: -------------------------------------------------------------------------------- 1 | message: Hello! 2 | -------------------------------------------------------------------------------- /samples/inventory/inventory: -------------------------------------------------------------------------------- 1 | [atlanta] 2 | atlanta-host ansible_host=127.0.0.1 3 | 4 | [raleigh] 5 | raleigh-host ansible_host=127.0.0.1 6 | 7 | [dbservers] 8 | db1 ansible_host=127.0.0.1 9 | db2 ansible_host=127.0.0.1 10 | 11 | [webservers] 12 | web1 ansible_host=127.0.0.1 13 | web2 ansible_host=127.0.0.1 14 | 15 | [backup] 16 | db2 ansible_host=127.0.0.1 17 | web2 ansible_host=127.0.0.1 18 | 19 | [atlanta:vars] 20 | region=atlanta 21 | 22 | [raleigh:vars] 23 | region=raleigh 24 | 25 | [southeast:children] 26 | atlanta 27 | raleigh 28 | 29 | [southeast:vars] 30 | region=southeast 31 | 32 | [usa:children] 33 | southeast 34 | 35 | [usa:vars] 36 | region=usa 37 | -------------------------------------------------------------------------------- /samples/inventory/inventory_example.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play runs on hosts in atlanta group 3 | hosts: atlanta 4 | connection: local 5 | tasks: 6 | - name: "Atlanta group" 7 | debug: var=region 8 | 9 | - name: Play runs on hosts in raleigh group 10 | hosts: raleigh 11 | connection: local 12 | tasks: 13 | - name: "Raleigh group" 14 | debug: var=region 15 | 16 | - name: Play runs in southeast group that includes atlanta and raleigh 17 | hosts: southeast 18 | connection: local 19 | tasks: 20 | - name: "Southeast group" 21 | debug: var=region 22 | 23 | - name: Play runs in usa group that includes southeast 24 | hosts: usa 25 | connection: local 26 | tasks: 27 | - name: "USA group" 28 | debug: var=region 29 | 30 | - hosts: dbservers:webservers 31 | connection: local 32 | tasks: 33 | - name: task runs on dbservers or webservers 34 | debug: var=hostvars[inventory_hostname]["ansible_fqdn"] 35 | 36 | - hosts: dbservers:!backup 37 | connection: local 38 | tasks: 39 | - name: task runs on hosts that are in dbservers AND NOT in backup 40 | debug: var=hostvars[inventory_hostname]['ansible_fqdn'] 41 | 42 | - hosts: dbservers:webservers:!backup 43 | connection: local 44 | tasks: 45 | - name: task runs on hosts that are in dbservers,webservers AND NOT in backup 46 | debug: var=hostvars[inventory_hostname].ansible_fqdn 47 | 48 | - hosts: webservers:&backup 49 | connection: local 50 | tasks: 51 | - name: task runs on hosts that are in webservers AND in backup 52 | debug: var=hostvars[inventory_hostname].ansible_fqdn 53 | 54 | - hosts: webservers[0]:backup[-1] 55 | connection: local 56 | tasks: 57 | - name: task runs on the first host in webservers and on the last host in backup 58 | debug: var=hostvars[inventory_hostname].ansible_fqdn 59 | 60 | -------------------------------------------------------------------------------- /samples/local_facts/example_local-facts.yml: -------------------------------------------------------------------------------- 1 | - name: Setting local facts 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Ensure directory for ansible facts exists 6 | file: state=directory recurse=yes path=/etc/ansible/facts.d 7 | become: true 8 | become_user: root 9 | 10 | - name: Ensure INI example fact exists 11 | copy: src=ini_example.fact dest=/etc/ansible/facts.d 12 | become: true 13 | become_user: root 14 | 15 | - name: Ensure JSON example fact exists 16 | copy: src=json_example.fact dest=/etc/ansible/facts.d 17 | become: true 18 | become_user: root 19 | 20 | - name: Ensure EXECUTABLE example fact exists 21 | copy: src=exec_java.fact dest=/etc/ansible/facts.d mode="a+x" 22 | become: true 23 | become_user: root 24 | 25 | - name: Getting local fact 26 | hosts: localhost 27 | 28 | tasks: 29 | - name: Display variable from INI file 30 | debug: 31 | msg: "foo = {{ ansible_local.ini_example.general.foo }}" 32 | 33 | - name: Display variable from JSON file 34 | debug: 35 | msg: "Apache version = {{ ansible_local.json_example.software.apache.version }}" 36 | 37 | - name: Display variable from executable script 38 | debug: 39 | msg: "java = {{ ansible_local.exec_java.java_version }}" 40 | -------------------------------------------------------------------------------- /samples/local_facts/files/exec_java.fact: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | JAVA_VERSION=`java -version 2>&1 | awk -F '"' '/version/ {print $2}'` 4 | 5 | cat < (item=server1) => { 35 | # "changed": false, 36 | # "item": { 37 | # "disks": "3gb", 38 | # "name": "server1", 39 | # "network": { 40 | # "nic01": "100Gb", 41 | # "nic02": "10Gb" 42 | # }, 43 | # "ram": "15Gb" 44 | # }, 45 | # "msg": "server1" 46 | # } 47 | # ok: [localhost] => (item=server2) => { 48 | # "changed": false, 49 | # "item": { 50 | # "disks": "3gb", 51 | # "name": "server2", 52 | # "network": { 53 | # "nic01": "100Gb", 54 | # "nic02": "10Gb" 55 | # }, 56 | # "ram": "15Gb" 57 | # }, 58 | # "msg": "server2" 59 | # } 60 | 61 | # PLAY RECAP *************************************************************************************************************************************************** 62 | # localhost : ok=2 changed=0 unreachable=0 failed=0 -------------------------------------------------------------------------------- /samples/loops/loop-do-until.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | 3 | tasks: 4 | - shell: sleep 10 & 5 | 6 | - shell: ps -ef | grep 'sleep 10' | grep -v grep || echo 7 | register: result 8 | until: result.stdout_lines | length == 0 9 | retries: 11 10 | delay: 1 11 | 12 | 13 | #### 14 | 15 | # $ ansible-playbook loop-do-until.yml 16 | 17 | #### 18 | 19 | 20 | # PLAY [localhost] *************************************************************** 21 | 22 | # TASK [Gathering Facts] ********************************************************* 23 | # ok: [localhost] 24 | 25 | # TASK [command] ***************************************************************** 26 | # changed: [localhost] => {"changed": true, "cmd": "sleep 10 &", "delta": "0:00:01.011679", "end": "2018-03-13 21:54:10.539652", "rc": 0, "start": "2018-03-13 21:54:09.527973", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} 27 | 28 | # TASK [command] ***************************************************************** 29 | # FAILED - RETRYING: command (11 retries left). 30 | # FAILED - RETRYING: command (10 retries left). 31 | # FAILED - RETRYING: command (9 retries left). 32 | # FAILED - RETRYING: command (8 retries left). 33 | # FAILED - RETRYING: command (7 retries left). 34 | # FAILED - RETRYING: command (6 retries left). 35 | # FAILED - RETRYING: command (5 retries left). 36 | # changed: [localhost] => {"attempts": 8, "changed": true, "cmd": "ps -ef | grep 'sleep 10' | grep -v grep || echo", "delta": "0:00:00.070893", "end": "2018-03-13 21:54:20.163543", "rc": 0, "start": "2018-03-13 21:54:20.092650", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []} 37 | 38 | # PLAY RECAP ********************************************************************* 39 | # localhost : ok=3 changed=2 unreachable=0 failed=0 -------------------------------------------------------------------------------- /samples/loops/looping-over-fileglobs-example.yml: -------------------------------------------------------------------------------- 1 | - name: Looping over Fileglobs Example 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Show full path to each file in folder 6 | debug: msg="{{ item }}" 7 | with_fileglob: 8 | - files/* 9 | -------------------------------------------------------------------------------- /samples/loops/looping-over-files-example.yml: -------------------------------------------------------------------------------- 1 | - name: Looping over Files Example 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Print content of each file 6 | debug: msg="{{ item }}" 7 | with_file: 8 | - files/first_file 9 | - files/second_file 10 | -------------------------------------------------------------------------------- /samples/loops/looping-over-hashes-example.yml: -------------------------------------------------------------------------------- 1 | - name: Looping over Hashes Example 2 | hosts: localhost 3 | 4 | vars: 5 | users: 6 | alice: 7 | name: Alice Appleworth 8 | telephone: 123-456-7890 9 | bob: 10 | name: Bob Bananarama 11 | telephone: 987-654-3210 12 | 13 | tasks: 14 | - name: Print phone records 15 | debug: 16 | msg: "User {{ item.key }} is {{ item.value.name }} ({{ item.value.telephone }})" 17 | with_dict: "{{ users }}" 18 | -------------------------------------------------------------------------------- /samples/loops/looping-over-integer-sequences-example.yml: -------------------------------------------------------------------------------- 1 | - name: Looping over Integer Sequences Example 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Print even numbers from 0 to 10 in format "number-X" 6 | debug: msg="{{ item }}" 7 | with_sequence: start=0 end=16 stride=2 format=number-%d 8 | 9 | - name: Print numbers from 1 to 3 10 | debug: msg="{{ item }}" 11 | with_sequence: count=3 12 | -------------------------------------------------------------------------------- /samples/loops/looping-over-inventory.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | 3 | tasks: 4 | # show all the hosts in the inventory 5 | - debug: 6 | msg: "{{ item }}" 7 | with_items: 8 | - "{{ groups['all'] }}" 9 | 10 | # show all the hosts in the current play 11 | - debug: 12 | msg: "{{ item }}" 13 | with_items: 14 | - "{{ play_hosts }}" 15 | 16 | # show all the hosts in the inventory 17 | - debug: 18 | msg: "{{ item }}" 19 | with_inventory_hostnames: 20 | - all 21 | 22 | # show all the hosts matching the pattern, ie all but the group www 23 | - debug: 24 | msg: "{{ item }}" 25 | with_inventory_hostnames: 26 | - all:!www 27 | -------------------------------------------------------------------------------- /samples/loops/looping-over-parallel-sets-data-example.yml: -------------------------------------------------------------------------------- 1 | - name: Looping over Parallel Sets of Data Example 2 | hosts: localhost 3 | 4 | vars: 5 | letters: ['a', 'b', 'c', 'd'] 6 | numbers: [1, 2, 3, 4] 7 | 8 | tasks: 9 | - name: Print letters with appropriate numbers 10 | debug: msg="{{ item.0 }} and {{ item.1 }}" 11 | with_together: 12 | - "{{ letters }}" 13 | - "{{ numbers }}" 14 | -------------------------------------------------------------------------------- /samples/loops/looping-over-subelements-example.yml: -------------------------------------------------------------------------------- 1 | - name: Looping over Subelements Example 2 | hosts: localhost 3 | 4 | vars: 5 | users: 6 | - name: alice 7 | files: 8 | - files/first_file 9 | properties: 10 | password: 11 | - alice-123 12 | groups: 13 | - "root" 14 | - "wheel" 15 | - name: bob 16 | files: 17 | - files/second_file 18 | properties: 19 | password: 20 | - bob-789 21 | groups: 22 | - "root" 23 | - "wheel" 24 | 25 | tasks: 26 | - name: Print users with appropriate file content 27 | debug: msg="User {{ item.0.name }} wrote '{{ lookup ('file', item.1) }}' in file {{ item.1 }}" 28 | with_subelements: 29 | - "{{ users }}" 30 | - files 31 | - name: Print users with appropriate properties 32 | debug: msg="User {{ item.0.name }} is in groups {{ item.0.properties.groups | join(',') }} and has password {{ item.1 }}" 33 | with_subelements: 34 | - "{{ users }}" 35 | - properties.password 36 | -------------------------------------------------------------------------------- /samples/loops/looping-with-register.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | 3 | tasks: 4 | - debug: var=item 5 | with_items: 6 | - "one" 7 | - "two" 8 | register: looprg 9 | 10 | - debug: var=looprg 11 | 12 | # #### 13 | # $ ansible-playbook looping-with-register.yml 14 | # #### 15 | 16 | # #### 17 | # PLAY [localhost] *************************************************************** 18 | 19 | # TASK [Gathering Facts] ********************************************************* 20 | # ok: [localhost] 21 | 22 | # TASK [debug] ******************************************************************* 23 | # ok: [localhost] => (item=one) => { 24 | # "changed": false, 25 | # "item": "one" 26 | # } 27 | # ok: [localhost] => (item=two) => { 28 | # "changed": false, 29 | # "item": "two" 30 | # } 31 | 32 | # TASK [debug] ******************************************************************* 33 | # ok: [localhost] => { 34 | # "looprg": { 35 | # "changed": false, 36 | # "msg": "All items completed", 37 | # "results": [ 38 | # { 39 | # "_ansible_ignore_errors": null, 40 | # "_ansible_item_result": true, 41 | # "_ansible_no_log": false, 42 | # "_ansible_verbose_always": true, 43 | # "changed": false, 44 | # "failed": false, 45 | # "item": "one" 46 | # }, 47 | # { 48 | # "_ansible_ignore_errors": null, 49 | # "_ansible_item_result": true, 50 | # "_ansible_no_log": false, 51 | # "_ansible_verbose_always": true, 52 | # "changed": false, 53 | # "failed": false, 54 | # "item": "two" 55 | # } 56 | # ] 57 | # } 58 | # } 59 | 60 | # PLAY RECAP ******************************************************************** 61 | # localhost : ok=3 changed=0 unreachable=0 failed=0 -------------------------------------------------------------------------------- /samples/loops/loops-with-indexes.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | 3 | tasks: 4 | - name: indexed loop demo 5 | debug: 6 | msg: "{{ item.1 }} at position {{ item.0 }}" 7 | with_indexed_items: 8 | - "apple" 9 | - "pear" 10 | - "banana" 11 | - "kiwi" 12 | 13 | 14 | #### 15 | 16 | # $ ansible-playbook loops-with-indexes.yml 17 | 18 | #### 19 | 20 | # PLAY [localhost] *************************************************************** 21 | 22 | # TASK [Gathering Facts] ********************************************************* 23 | # ok: [localhost] 24 | 25 | # TASK [indexed loop demo] ******************************************************* 26 | # ok: [localhost] => (item=(0, u'apple')) => { 27 | # "changed": false, 28 | # "item": [ 29 | # 0, 30 | # "apple" 31 | # ], 32 | # "msg": "apple at position 0" 33 | # } 34 | # ok: [localhost] => (item=(1, u'pear')) => { 35 | # "changed": false, 36 | # "item": [ 37 | # 1, 38 | # "pear" 39 | # ], 40 | # "msg": "pear at position 1" 41 | # } 42 | # ok: [localhost] => (item=(2, u'banana')) => { 43 | # "changed": false, 44 | # "item": [ 45 | # 2, 46 | # "banana" 47 | # ], 48 | # "msg": "banana at position 2" 49 | # } 50 | # ok: [localhost] => (item=(3, u'kiwi')) => { 51 | # "changed": false, 52 | # "item": [ 53 | # 3, 54 | # "kiwi" 55 | # ], 56 | # "msg": "kiwi at position 3" 57 | # } 58 | 59 | # PLAY RECAP ********************************************************************* 60 | # localhost : ok=2 changed=0 unreachable=0 failed=0 -------------------------------------------------------------------------------- /samples/loops/nested-loop-example.yml: -------------------------------------------------------------------------------- 1 | - name: Nested Loops Example 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: print several users with multiple groups 6 | debug: msg="User {{ item[0] }} will be added to group {{ item[1] }}" 7 | with_nested: 8 | - [ 'alice', 'bob' ] 9 | - [ 'wheel', 'root' ] 10 | -------------------------------------------------------------------------------- /samples/loops/random-choices-example.yml: -------------------------------------------------------------------------------- 1 | - name: Random Choices Example 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Print random phrase" 6 | debug: msg="{{ item }}" 7 | with_random_choice: 8 | - "go through the door" 9 | - "drink from the goblet" 10 | - "press the red button" 11 | - "do nothing" 12 | -------------------------------------------------------------------------------- /samples/loops/standart-loop-example.yml: -------------------------------------------------------------------------------- 1 | - name: Standart Loops Example 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: print several users 6 | debug: msg="User {{ item.name }} will be addedd to group {{ item.groups }}" 7 | with_items: 8 | - { name: 'alice', groups: 'wheel' } 9 | - { name: 'bob', groups: 'root' } 10 | -------------------------------------------------------------------------------- /samples/modules/custom_modules_examples.yml: -------------------------------------------------------------------------------- 1 | - name: Examples Of Using Custom Modules 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Using simple bash module 6 | bash-module: phrase="Hello_world" 7 | register: result 8 | 9 | - name: Show output 10 | debug: var=result 11 | 12 | - name: Using simple python module 13 | python-module: 14 | register: result 15 | 16 | - name: Show output 17 | debug: var=result 18 | 19 | - name: Using module boilerplate 20 | boilerplate: file=directory owner=vagrant mode=0755 recurse=True 21 | register: result 22 | 23 | - name: Show output 24 | debug: var=result 25 | 26 | - name: Using module for adding custom ansible fact 27 | fact-module: myfact=myvalue 28 | 29 | - name: Show output 30 | debug: var=myfact 31 | -------------------------------------------------------------------------------- /samples/modules/library/bash-module.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $1 4 | 5 | ##------Checking input variables--------- 6 | 7 | if [ -z "$phrase" ]; then 8 | printf '{"failed": true, "msg": "Missing required arguments: phrase"}' 9 | exit 1 10 | fi 11 | 12 | printf '{"failed": false, "changed": false, "phrase": "%s"}' "$phrase" 13 | 14 | exit 0 15 | -------------------------------------------------------------------------------- /samples/modules/library/boilerplate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # libraries you import here, must be present on the target node. 4 | 5 | # You can defined other functions up here to make your code more modular. 6 | # These functions will need to be called from main(), either directly or through N number of other functions 7 | # that eventually lead back to main() 8 | 9 | def main(): 10 | 11 | module = AnsibleModule( 12 | argument_spec = dict( 13 | file = dict(default='file', choices=['file', 'directory']), 14 | owner = dict(required=True), 15 | mode = dict(required=True), 16 | recurse = dict(default=False, type='bool') 17 | ), 18 | supports_check_mode = True 19 | ) 20 | 21 | # Normalize params to make code cleaner 22 | file = module.params['file'] 23 | owner = module.params['owner'] 24 | mode = module.params['mode'] 25 | recurse = module.params['recurse'] 26 | 27 | # Do logic here, can be calls to other functions above main() 28 | 29 | # if it is time to exit, successfully 30 | module.exit_json(changed=True, created=file, owner=owner, permossions=mode) 31 | 32 | # if it is time to exit, with an error 33 | module.fail_json(msg='Some error message') 34 | 35 | if module.check_mode: 36 | # Check if any changes would be made but don't actually make those changes 37 | module.exit_json(changed=check_if_system_state_would_be_changed()) 38 | 39 | # import module snippets (must stay here after your code) 40 | from ansible.module_utils.basic import AnsibleModule 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /samples/modules/library/fact-module.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sys 4 | import json 5 | import shlex 6 | 7 | 8 | args_file = sys.argv[1] 9 | args_data = file(args_file).read() 10 | 11 | arguments = shlex.split(args_data) 12 | result = {} 13 | result["ansible_facts"] = {} 14 | for arg in arguments: 15 | 16 | if "=" in arg: 17 | 18 | key, value = arg.split("=") 19 | result["ansible_facts"][key] = value 20 | 21 | result['changed'] = True 22 | print(json.dumps(result)) 23 | -------------------------------------------------------------------------------- /samples/modules/library/python-module.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import datetime 4 | import json 5 | 6 | date = str(datetime.datetime.now()) 7 | print(json.dumps({ 8 | "time" : date 9 | })) 10 | -------------------------------------------------------------------------------- /samples/modules/python_module_boilerplate_example.yml: -------------------------------------------------------------------------------- 1 | - name: Using custom module boilerplate 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Show some info 6 | boilerplate: file=directory owner=vagrant mode=0755 recurse=True 7 | register: result 8 | 9 | - name: Show output 10 | debug: var=result 11 | 12 | -------------------------------------------------------------------------------- /samples/order_in_playbook/README.md: -------------------------------------------------------------------------------- 1 | # Ansible 'Order in playbook' example 2 | 3 | ## Resources: 4 | 5 | - [Ansible Docs](http://docs.ansible.com/ansible/playbooks_roles.html#roles) 6 | - [Demo Playbook](example_order.yml) 7 | 8 | ## Examples: 9 | 10 | ```sh 11 | $ ansible-playbook example_order.yml -c local 12 | ``` 13 | 14 | **Output:** 15 | 16 | ```sh 17 | 18 | PLAY [Order in playbook] ************************************************** 19 | 20 | TASK [Gathering Facts] **************************************************** 21 | ok: [localhost] 22 | 23 | TASK [Example of pre_task] ************************************************ 24 | ok: [localhost] => { 25 | "msg": "Good morning!" 26 | } 27 | 28 | TASK [some_role : Example of role_task] *********************************** 29 | ok: [localhost] => { 30 | "msg": "This is a task from 'some_role'" 31 | } 32 | 33 | TASK [Example of main task] *********************************************** 34 | changed: [localhost] 35 | 36 | RUNNING HANDLER [Some trigger] ******************************************** 37 | ok: [localhost] => { 38 | "msg": "Something triggers me to say Hello!" 39 | } 40 | 41 | TASK [Example of post-task] *********************************************** 42 | ok: [localhost] => { 43 | "msg": "Good evening!" 44 | } 45 | 46 | PLAY RECAP **************************************************************** 47 | localhost : ok=6 changed=1 unreachable=0 failed=0 48 | 49 | ``` 50 | 51 | -------------------------------------------------------------------------------- /samples/order_in_playbook/example_order.yml: -------------------------------------------------------------------------------- 1 | - name: Order in playbook 2 | hosts: localhost 3 | 4 | pre_tasks: 5 | - name: Example of pre_task 6 | debug: 7 | msg: "Good morning!" 8 | 9 | roles: 10 | - { role: some_role } 11 | 12 | tasks: 13 | 14 | - name: Example of main task 15 | shell: echo 'Hello world' 16 | notify: 17 | - Some trigger 18 | 19 | post_tasks: 20 | - name: Example of post-task 21 | debug: 22 | msg: "Good evening!" 23 | 24 | handlers: 25 | - name: Some trigger 26 | debug: 27 | msg: "Something triggered me to say Hello!" 28 | 29 | -------------------------------------------------------------------------------- /samples/order_in_playbook/roles/some_role/defaults/main.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/order_in_playbook/roles/some_role/defaults/main.yml -------------------------------------------------------------------------------- /samples/order_in_playbook/roles/some_role/handlers/main.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/order_in_playbook/roles/some_role/handlers/main.yml -------------------------------------------------------------------------------- /samples/order_in_playbook/roles/some_role/meta/main.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/order_in_playbook/roles/some_role/meta/main.yml -------------------------------------------------------------------------------- /samples/order_in_playbook/roles/some_role/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: Example of role_task 2 | debug: 3 | msg: "This is a task from 'some_role'" 4 | 5 | -------------------------------------------------------------------------------- /samples/order_in_playbook/roles/some_role/vars/main.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/order_in_playbook/roles/some_role/vars/main.yml -------------------------------------------------------------------------------- /samples/plugins/action/action_plugins/echo_action_no_module.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | from ansible.plugins.action import ActionBase 5 | import socket 6 | 7 | class ActionModule(ActionBase): 8 | 9 | def run(self, tmp=None, task_vars=None): 10 | 11 | if task_vars is None: 12 | task_vars = dict() 13 | 14 | result = super(ActionModule, self).run(tmp, task_vars) 15 | 16 | hostname = socket.gethostname() 17 | 18 | result['msg'] = ["Hello, I am a simple action plugin!"] 19 | result['msg'].append("I run on %s." % hostname) 20 | result['msg'].append("I don't have a corresponding module, so I can only be run with action.") 21 | result['msg'].append("I can see and use playbook variables like test_variable = %s." % task_vars['test_variable']) 22 | result['msg'].append("I can also access global ansible variables like ansible_version = %s." % task_vars['ansible_version']) 23 | result['_ansible_verbose_always'] = True 24 | 25 | return result 26 | -------------------------------------------------------------------------------- /samples/plugins/action/action_plugins/echo_action_with_module.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | from ansible.plugins.action import ActionBase 5 | import socket 6 | 7 | class ActionModule(ActionBase): 8 | 9 | def run(self, tmp=None, task_vars=None): 10 | 11 | if task_vars is None: 12 | task_vars = dict() 13 | 14 | result = super(ActionModule, self).run(tmp, task_vars) 15 | 16 | secret = self._task.args.get('secret', None) 17 | test_variable = self._task.args.get('test_variable', None) 18 | 19 | result['_ansible_verbose_always'] = True 20 | 21 | hostname = socket.gethostname() 22 | 23 | with open(secret, "r") as file: 24 | secret_text = file.read().replace('\n', '') 25 | 26 | pass_vars = dict() 27 | pass_vars.update( 28 | ansible_version=task_vars['ansible_version'], 29 | secret=secret_text 30 | ) 31 | 32 | result['action_msg'] = ["Hello, I am another action plugin!"] 33 | result['action_msg'].append("I run on %s." % hostname) 34 | result['action_msg'].append("Since I have a corresponding empty module file I can be called the same way as modules.") 35 | result['action_msg'].append("I call module echo_module and pass some playbook and global ansibe variables to it along with my test_variable = %s" % test_variable) 36 | result['action_msg'].append("Also I read a secret from a file located on ansible host machine in %s and pass it to the module." % secret) 37 | 38 | new_module_args = dict() 39 | new_module_args.update( 40 | dict( 41 | test_argument=test_variable, 42 | task_var=pass_vars, 43 | ), 44 | ) 45 | 46 | result.update( 47 | self._execute_module( 48 | module_name='echo_module', 49 | module_args=new_module_args, 50 | ) 51 | ) 52 | 53 | return result 54 | 55 | -------------------------------------------------------------------------------- /samples/plugins/action/demo.yml: -------------------------------------------------------------------------------- 1 | - name: ANSIBLE PLUGINS DEMO 2 | hosts: all 3 | 4 | vars: 5 | test_variable: "test_text" 6 | 7 | tasks: 8 | 9 | - name: test module 10 | echo_module: 11 | test_argument: "some_text" 12 | 13 | - name: test simple action type 1 14 | action: echo_action_no_module 15 | 16 | - name: test simple action type 2 17 | echo_action_with_module: 18 | secret: "./secretfile" 19 | test_variable: "my_variable_value" 20 | -------------------------------------------------------------------------------- /samples/plugins/action/library/echo_action_with_module: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/plugins/action/library/echo_action_with_module -------------------------------------------------------------------------------- /samples/plugins/action/library/echo_module: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | from ansible.module_utils.basic import AnsibleModule 4 | import socket 5 | 6 | def main(): 7 | 8 | module = AnsibleModule( 9 | argument_spec = dict( 10 | test_argument = dict(required=True, type='str'), 11 | task_var = dict(default={}, type='dict') 12 | ) 13 | ) 14 | 15 | args = module.params 16 | 17 | hostname = socket.gethostname() 18 | 19 | msg = [] 20 | msg.append("Hello! I am a module!") 21 | msg.append("I am executed on %s." % hostname) 22 | msg.append("I require one argument - test_argument = %s" % args['test_argument']) 23 | if args['task_var']: 24 | msg.append("Since I am called by action plugin I now have access to a variety of variables.") 25 | msg.append("Like ansible_version = %s." % args['task_var']['ansible_version']) 26 | msg.append("Or the secret text = '%s' from a file on ansible host." % args['task_var']['secret']) 27 | else: 28 | msg.append("Since I am executed on remote host I don't have access to playbook and environment variables") 29 | 30 | module.exit_json(_ansible_verbose_always=True, module_msg=msg) 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /samples/plugins/action/secretfile: -------------------------------------------------------------------------------- 1 | somesecret 2 | -------------------------------------------------------------------------------- /samples/plugins/callback/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | callback_whitelist = cb_stdout, cb_log, cb_notify 3 | stdout_callback = cb_stdout 4 | 5 | retry_files_enabled = False 6 | -------------------------------------------------------------------------------- /samples/plugins/callback/callback_plugins/cb_log.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | from ansible.plugins.callback import CallbackBase 5 | from datetime import datetime 6 | 7 | class CallbackModule(CallbackBase): 8 | 9 | CALLBACK_VERSION = 2.0 10 | CALLBACK_TYPE = 'log' 11 | CALLBACK_NAME = 'cb_log' 12 | CALLBACK_NEEDS_WHITELIST = True 13 | 14 | def __init__(self, *args, **kwargs): 15 | super(CallbackModule, self).__init__(*args, **kwargs) 16 | self.start_time = datetime.now() 17 | 18 | def v2_on_any(self, *args, **kwargs): 19 | with open('log.txt', 'a+') as log: 20 | log.write("\nArgs: %s Kwargs: %s\n" % (args, kwargs)) 21 | 22 | def days_hours_minutes_seconds(self, runtime): 23 | minutes = (runtime.seconds // 60) % 60 24 | r_seconds = runtime.seconds - (minutes * 60) 25 | return runtime.days, runtime.seconds // 3600, minutes, r_seconds 26 | 27 | def show(self, result): 28 | if result.is_failed(): 29 | colour = 'magenta' 30 | elif result.is_skipped(): 31 | colour = 'blue' 32 | else: 33 | colour = 'yellow' 34 | with open('log.txt', 'a+') as log: 35 | log.write("\n%s | HOST: %s | failed: %s | skipped: %s | unreachable: %s | changed: %s\n" 36 | % (result._task, result._host, result.is_failed(), result.is_skipped(), result.is_unreachable(), result.is_changed())) 37 | log.write("Output: %s\n" % result._task_fields['args'].values()) 38 | 39 | def v2_runner_on_failed(self, result, ignore_errors=False): 40 | self.show(result) 41 | 42 | def v2_runner_on_ok(self, result): 43 | self.show(result) 44 | 45 | def v2_runner_on_skipped(self, result): 46 | self.show(result) 47 | 48 | def v2_runner_on_unreachable(self, result): 49 | self.show(result) 50 | 51 | def v2_playbook_on_stats(self, stats): 52 | end_time = datetime.now() 53 | runtime = end_time - self.start_time 54 | with open('log.txt', 'a+') as log: 55 | log.write("\nPlaybook run took %s days, %s hours, %s minutes, %s seconds\n" % (self.days_hours_minutes_seconds(runtime))) 56 | -------------------------------------------------------------------------------- /samples/plugins/callback/callback_plugins/cb_notify.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | from ansible.plugins.callback import CallbackBase 5 | import smtplib 6 | from email.mime.text import MIMEText 7 | 8 | class CallbackModule(CallbackBase): 9 | 10 | CALLBACK_VERSION = 2.0 11 | CALLBACK_TYPE = 'notify' 12 | CALLBACK_NAME = 'cb_notify' 13 | CALLBACK_NEEDS_WHITELIST = True 14 | 15 | def __init__(self, *args, **kwargs): 16 | super(CallbackModule, self).__init__(*args, **kwargs) 17 | self.play = None 18 | 19 | def v2_playbook_on_play_start(self, play): 20 | self.play = play 21 | 22 | def v2_playbook_on_stats(self, stats): 23 | msg = MIMEText("Playbook execution finished: ok - %s changed - %s skipped - %s failures - %s" % (stats.ok, stats.changed, stats.skipped, stats.failures)) 24 | msg['Subject'] = 'Test playbook finished' 25 | msg['From'] = 'test@gmail.com' 26 | msg['To'] = '%s' % self.play.vars['email'] 27 | if self.play.vars['email']: 28 | send = smtplib.SMTP('localhost') 29 | send.sendmail(msg['From'], [msg['To']], msg.as_string()) 30 | send.quit() 31 | -------------------------------------------------------------------------------- /samples/plugins/callback/callback_plugins/cb_stdout.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | from ansible.plugins.callback import CallbackBase 5 | 6 | class CallbackModule(CallbackBase): 7 | 8 | CALLBACK_VERSION = 2.0 9 | CALLBACK_TYPE = 'stdout' 10 | CALLBACK_NAME = 'cb_stdout' 11 | CALLBACK_NEEDS_WHITELIST = True 12 | 13 | def __init__(self, *args, **kwargs): 14 | super(CallbackModule, self).__init__(*args, **kwargs) 15 | 16 | def v2_playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, 17 | confirm=False, salt_size=None, salt=None, default=None): 18 | self._display.display("We can modify actions like variable prompts. Btw, do input your email address:", color='cyan') 19 | 20 | def show(self, result, colour): 21 | self._display.display("\n%s | HOST: %s | failed: %s | skipped: %s | unreachable: %s | changed: %s\n" 22 | % (result._task, result._host, result.is_failed(), result.is_skipped(), result.is_unreachable(), result.is_changed())) 23 | self._display.display("Output: %s\n" % result._task_fields['args'].values(), color=colour) 24 | 25 | def v2_runner_on_failed(self, result, ignore_errors=False): 26 | self.show(result, 'magenta') 27 | 28 | def v2_runner_on_ok(self, result): 29 | self.show(result, 'yellow') 30 | 31 | def v2_runner_on_skipped(self, result): 32 | self.show(result, 'blue') 33 | 34 | def v2_runner_on_unreachable(self, result): 35 | self.show(result, 'red') 36 | 37 | -------------------------------------------------------------------------------- /samples/plugins/callback/demo.yml: -------------------------------------------------------------------------------- 1 | - name: ANSIBLE PLUGINS DEMO 2 | hosts: all 3 | 4 | vars_prompt: 5 | 6 | - name: email 7 | 8 | tasks: 9 | 10 | - name: 11 | debug: 12 | msg: "In this playbook we use 3 callback plugins configured in ansible.cfg." 13 | 14 | - name: 15 | debug: 16 | msg: "First plugin is cb_stdout. It is configured to be the stdout plugin. All output you see is processed by it. Only one stdout plugin can be active at a time." 17 | when: false 18 | 19 | - name: 20 | fail: 21 | msg: "Second plugin is cb_log. It writes output to logfile log.txt with some additional information like time it took to run playbook and parameters of yeah step in playbook, which could be useful for debugging." 22 | ignore_errors: true 23 | 24 | - name: 25 | fail: 26 | msg: "Third plugin will send you an email notification upon playbook completion with its status if you have entered a valid email when prompted. It has access to play variables through playbook_on_play_start method." 27 | -------------------------------------------------------------------------------- /samples/plugins/connection/README.md: -------------------------------------------------------------------------------- 1 | To perform this example run any docker Alpine container (preferably without pre-installed python). 2 | 3 | Run 4 | ansible-playbook -i , demo.yml -c docker_plugin 5 | 6 | Connection plug-in will pre-install python inside the container. 7 | -------------------------------------------------------------------------------- /samples/plugins/connection/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | connection_plugins = ./connection_plugins/ 3 | retry_files_enabled = False 4 | -------------------------------------------------------------------------------- /samples/plugins/connection/demo.yml: -------------------------------------------------------------------------------- 1 | - name: ANSIBLE CONNECTION PLUGIN DEMO 2 | hosts: all 3 | 4 | tasks: 5 | 6 | - name: story 7 | debug: 8 | msg: "Connection plugin defines how ansible communicates with the target host." 9 | 10 | - name: some more story 11 | debug: 12 | msg: "The necessary methods are: connect, close, exec_command, put_file, fetch_file" 13 | 14 | - name: Testing fetch functionality (is the only one not used during pre-run tasks) 15 | fetch: 16 | src: /etc/fstab 17 | dest: /tmp/ 18 | flat: yes 19 | -------------------------------------------------------------------------------- /samples/project_structure/common.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # file: common.yml 3 | - hosts: single_server 4 | roles: 5 | - common 6 | 7 | -------------------------------------------------------------------------------- /samples/project_structure/dbservers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # file: dbservers.yml 3 | - hosts: dbservers 4 | roles: 5 | - dbserver 6 | -------------------------------------------------------------------------------- /samples/project_structure/filter_plugins/some_plugin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/project_structure/filter_plugins/some_plugin -------------------------------------------------------------------------------- /samples/project_structure/inventories/production/group_vars/all: -------------------------------------------------------------------------------- 1 | --- 2 | # file: group_vars/all 3 | ntp: ntp-boston.example.com 4 | backup: backup-boston.example.com 5 | -------------------------------------------------------------------------------- /samples/project_structure/inventories/production/group_vars/atlanta: -------------------------------------------------------------------------------- 1 | --- 2 | # file: group_vars/atlanta 3 | ntp: ntp-atlanta.example.com 4 | backup: backup-atlanta.example.com 5 | -------------------------------------------------------------------------------- /samples/project_structure/inventories/production/group_vars/webservers: -------------------------------------------------------------------------------- 1 | --- 2 | # file: group_vars/webservers 3 | apacheMaxRequestsPerChild: 3000 4 | apacheMaxClients: 900 5 | -------------------------------------------------------------------------------- /samples/project_structure/inventories/production/host_vars/db-bos-1.example.com: -------------------------------------------------------------------------------- 1 | --- 2 | # file: host_vars/db-bos-1.example.com 3 | foo_agent_port: 86 4 | bar_agent_port: 99 5 | -------------------------------------------------------------------------------- /samples/project_structure/inventories/production/hosts: -------------------------------------------------------------------------------- 1 | # file: production 2 | 3 | [atlanta-webservers] 4 | www-atl-1.example.com 5 | www-atl-2.example.com 6 | 7 | [boston-webservers] 8 | www-bos-1.example.com 9 | www-bos-2.example.com 10 | 11 | [atlanta-dbservers] 12 | db-atl-1.example.com 13 | db-atl-2.example.com 14 | 15 | [boston-dbservers] 16 | db-bos-1.example.com 17 | 18 | # webservers in all geos 19 | [webservers:children] 20 | atlanta-webservers 21 | boston-webservers 22 | 23 | # dbservers in all geos 24 | [dbservers:children] 25 | atlanta-dbservers 26 | boston-dbservers 27 | 28 | # everything in the atlanta geo 29 | [atlanta:children] 30 | atlanta-webservers 31 | atlanta-dbservers 32 | 33 | # everything in the boston geo 34 | [boston:children] 35 | boston-webservers 36 | boston-dbservers 37 | -------------------------------------------------------------------------------- /samples/project_structure/inventories/staging/group_vars/group1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/project_structure/inventories/staging/group_vars/group1 -------------------------------------------------------------------------------- /samples/project_structure/inventories/staging/group_vars/group2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/project_structure/inventories/staging/group_vars/group2 -------------------------------------------------------------------------------- /samples/project_structure/inventories/staging/host_vars/stagehost1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/project_structure/inventories/staging/host_vars/stagehost1 -------------------------------------------------------------------------------- /samples/project_structure/inventories/staging/host_vars/stagehost2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/project_structure/inventories/staging/host_vars/stagehost2 -------------------------------------------------------------------------------- /samples/project_structure/inventories/staging/hosts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/project_structure/inventories/staging/hosts -------------------------------------------------------------------------------- /samples/project_structure/library/some_module: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/samples/project_structure/library/some_module -------------------------------------------------------------------------------- /samples/project_structure/roles/common/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | 5 | # Use the new container infrastructure 6 | sudo: false 7 | 8 | # Install ansible 9 | addons: 10 | apt: 11 | packages: 12 | - python-pip 13 | 14 | install: 15 | # Install ansible 16 | - pip install ansible 17 | 18 | # Check ansible version 19 | - ansible --version 20 | 21 | # Create ansible.cfg with correct roles_path 22 | - printf '[defaults]\nroles_path=../' >ansible.cfg 23 | 24 | script: 25 | # Basic role syntax check 26 | - ansible-playbook tests/test.yml -i tests/inventory --syntax-check 27 | 28 | notifications: 29 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ -------------------------------------------------------------------------------- /samples/project_structure/roles/common/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /samples/project_structure/roles/common/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for my_role 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/common/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for my_role 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/common/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: 3 | - { role: webserver, apache_port: 80, n: 1 } 4 | - { role: dbserver, dbname: blarg, n: 2} 5 | -------------------------------------------------------------------------------- /samples/project_structure/roles/common/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for my_role 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/common/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost -------------------------------------------------------------------------------- /samples/project_structure/roles/common/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - my_role -------------------------------------------------------------------------------- /samples/project_structure/roles/common/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for my_role 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/dbserver/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | 5 | # Use the new container infrastructure 6 | sudo: false 7 | 8 | # Install ansible 9 | addons: 10 | apt: 11 | packages: 12 | - python-pip 13 | 14 | install: 15 | # Install ansible 16 | - pip install ansible 17 | 18 | # Check ansible version 19 | - ansible --version 20 | 21 | # Create ansible.cfg with correct roles_path 22 | - printf '[defaults]\nroles_path=../' >ansible.cfg 23 | 24 | script: 25 | # Basic role syntax check 26 | - ansible-playbook tests/test.yml -i tests/inventory --syntax-check 27 | 28 | notifications: 29 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ -------------------------------------------------------------------------------- /samples/project_structure/roles/dbserver/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /samples/project_structure/roles/dbserver/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for dbserver 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/dbserver/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for dbserver 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/dbserver/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for dbserver 3 | 4 | -------------------------------------------------------------------------------- /samples/project_structure/roles/dbserver/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost -------------------------------------------------------------------------------- /samples/project_structure/roles/dbserver/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - dbserver -------------------------------------------------------------------------------- /samples/project_structure/roles/dbserver/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for dbserver 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/webserver/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | 5 | # Use the new container infrastructure 6 | sudo: false 7 | 8 | # Install ansible 9 | addons: 10 | apt: 11 | packages: 12 | - python-pip 13 | 14 | install: 15 | # Install ansible 16 | - pip install ansible 17 | 18 | # Check ansible version 19 | - ansible --version 20 | 21 | # Create ansible.cfg with correct roles_path 22 | - printf '[defaults]\nroles_path=../' >ansible.cfg 23 | 24 | script: 25 | # Basic role syntax check 26 | - ansible-playbook tests/test.yml -i tests/inventory --syntax-check 27 | 28 | notifications: 29 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ -------------------------------------------------------------------------------- /samples/project_structure/roles/webserver/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /samples/project_structure/roles/webserver/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for webserver 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/webserver/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for webserver 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/webserver/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for webserver 3 | -------------------------------------------------------------------------------- /samples/project_structure/roles/webserver/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost -------------------------------------------------------------------------------- /samples/project_structure/roles/webserver/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - webserver -------------------------------------------------------------------------------- /samples/project_structure/roles/webserver/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for webserver 3 | -------------------------------------------------------------------------------- /samples/project_structure/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # file: site.yml 3 | - include: webservers.yml 4 | - include: dbservers.yml 5 | -------------------------------------------------------------------------------- /samples/project_structure/webservers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # file: webservers.yml 3 | - hosts: webservers 4 | roles: 5 | - webserver 6 | -------------------------------------------------------------------------------- /samples/registered_vars/playbook.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | tasks: 4 | - name: "Shell step 'cat playbook.yml'. Output is registered to result variable" 5 | shell: cat playbook.yml 6 | register: result 7 | - name: "Registering custom fact from the formatted result variable" 8 | set_fact: from_yaml="{{ result.stdout | from_yaml }}" 9 | - name: "Output of result.stdout" 10 | debug: var=result.stdout 11 | - name: "Output of the custom fact" 12 | debug: var=from_yaml 13 | -------------------------------------------------------------------------------- /samples/special-variables/roles/sample-role/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - debug: 2 | msg: >- 3 | The names of the rules currently imported into the current play. 4 | role_name = {{ role_names }} 5 | 6 | The path to the dir of the currently running role 7 | role_path = {{ role_path }} 8 | -------------------------------------------------------------------------------- /samples/strategies/inventory: -------------------------------------------------------------------------------- 1 | localhost ansible_connection=local 2 | 35.184.194.164 3 | 35.184.156.100 4 | -------------------------------------------------------------------------------- /samples/strategies/strategy_example.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | strategy: linear 4 | tasks: 5 | - name: "First step" 6 | debug: msg="Step 1. Something is done here" 7 | - name: "Second step" 8 | debug: msg="Step 2. Something is done here" 9 | - name: "Third step" 10 | debug: msg="Step 3. Something is done here" 11 | 12 | -------------------------------------------------------------------------------- /samples/templates/README.md: -------------------------------------------------------------------------------- 1 | # Templates/jinja2 2 | 3 | [http://docs.ansible.com/ansible/template_module.html#template-templates-a-file-out-to-a-remote-server] 4 | 5 | 6 | - [demo playbook](vhost.yml) 7 | - [virtual host template](templates/virtual-host.conf.j2) 8 | - [generated config](templates/virtual-host.conf) 9 | 10 | ```sh 11 | $ ansible-playbook vhost.yml 12 | ``` 13 | 14 | ```sh 15 | PLAY *************************************************************************** 16 | 17 | TASK [setup] ******************************************************************* 18 | ok: [localhost] 19 | 20 | TASK [Generating virtual hosts config] ***************************************** 21 | changed: [localhost] 22 | 23 | PLAY RECAP ********************************************************************* 24 | localhost : ok=2 changed=1 unreachable=0 failed=0 25 | ``` 26 | 27 | Generated virtual hosts config: 28 | ```sh 29 | 30 | ServerName www.domain.com 31 | DocumentRoot /www/domain_com 32 | 33 | AllowOverride All 34 | Options -Indexes FollowSymLinks 35 | Order allow,deny 36 | Allow from all 37 | 38 | 39 | 40 | 41 | ServerName www.domain.by 42 | DocumentRoot /www/domain_by 43 | ServerAdmin webmaster@domain.by 44 | 45 | AllowOverride All 46 | Options -Indexes FollowSymLinks 47 | Order allow,deny 48 | Allow from all 49 | 50 | 51 | ``` 52 | -------------------------------------------------------------------------------- /samples/templates/templates/virtual-host.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerName www.domain.com 3 | DocumentRoot /www/domain_com 4 | 5 | AllowOverride All 6 | Options -Indexes FollowSymLinks 7 | Order allow,deny 8 | Allow from all 9 | 10 | 11 | 12 | 13 | ServerName www.domain.by 14 | DocumentRoot /www/domain_by 15 | ServerAdmin webmaster@domain.by 16 | 17 | AllowOverride All 18 | Options -Indexes FollowSymLinks 19 | Order allow,deny 20 | Allow from all 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /samples/templates/templates/virtual-host.conf.j2: -------------------------------------------------------------------------------- 1 | {% for vhost in apache_vhosts %} 2 | 3 | ServerName {{ vhost.servername }} 4 | DocumentRoot {{ vhost.documentroot }} 5 | {% if vhost.serveradmin is defined %} 6 | ServerAdmin {{ vhost.serveradmin }} 7 | {% endif %} 8 | 9 | AllowOverride All 10 | Options -Indexes FollowSymLinks 11 | Order allow,deny 12 | Allow from all 13 | 14 | 15 | 16 | {% endfor %} 17 | -------------------------------------------------------------------------------- /samples/templates/vhost.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | vars: 4 | apache_vhosts: 5 | - {servername: "www.domain.com", documentroot: "/www/domain_com"} 6 | - {servername: "www.domain.by", documentroot: "/www/domain_by", serveradmin: "webmaster@domain.by"} 7 | tasks: 8 | - name: "Generating virtual hosts config" 9 | template: 10 | src: templates/virtual-host.conf.j2 11 | dest: templates/virtual-host.conf 12 | mode: '0644' 13 | backup: yes 14 | -------------------------------------------------------------------------------- /samples/variables/host_vars.yml: -------------------------------------------------------------------------------- 1 | myvar: myvar defined in the host scope 2 | myvar2: myvar2 defined in the host scope 3 | -------------------------------------------------------------------------------- /samples/variables/inventory: -------------------------------------------------------------------------------- 1 | [local] 2 | localhost 3 | 4 | [local:vars] 5 | myvar=myvar defined in group vars 6 | -------------------------------------------------------------------------------- /samples/variables/vars_example.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | tasks: 4 | - debug: var=myvar 5 | 6 | - hosts: localhost 7 | connection: local 8 | vars: 9 | myvar: myvar defined in playbook 10 | tasks: 11 | - debug: var=myvar 12 | 13 | - hosts: localhost 14 | connection: local 15 | vars: 16 | myvar: myvar defined in vars section 17 | myvar2: myvar2 defined in vars section 18 | tasks: 19 | - name: Variables from Play scope 20 | debug: var={{ item }} 21 | with_items: 22 | - myvar 23 | - myvar2 24 | - name: Variables from Host scope 25 | include_vars: host_vars.yml 26 | - debug: var=hostvars[inventory_hostname]["{{ item }}"] 27 | with_items: 28 | - myvar 29 | - myvar2 30 | 31 | - hosts: localhost 32 | connection: local 33 | tasks: 34 | - name: Example of the builtin variable ansible-version 35 | debug: var=ansible_version 36 | -------------------------------------------------------------------------------- /samples/vault/resources/secret-file-for-copy.txt: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 30313465343738336165313934383064396166646238663333616364303665363131656363613762 3 | 3039623938666139333133666537333863333065393834390a643961396562373662336137356634 4 | 66393834316162396662333562663536353037633131323335386664363033366165373431346133 5 | 3733636134353339350a316464343734396361623539636531303166643939343530646630326634 6 | 38393433613339323331323832623064633064393936356238306165313066393461 7 | -------------------------------------------------------------------------------- /samples/vault/resources/secret-file-for-template.txt: -------------------------------------------------------------------------------- 1 | Many many secred data here 2 | 3 | {{ nonsecret }} 4 | 5 | Many many secred data here 6 | -------------------------------------------------------------------------------- /samples/vault/resources/secret-variables.yml: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 66666336636165376338313165616237383634303533373138353363353537313238663736633264 3 | 3637663266366538373339306331346666396565303864650a653962663033343731333637613234 4 | 32373336666335383137303531323635366236323838366361346339613462323666363333383432 5 | 3361313739383266370a636166663766393339623866633763616266643834346335376431336439 6 | 32346339313439633432353331336432633639633962323737633737303839353038663965356230 7 | 3830323933343261616333333938336363636335663138393830 8 | -------------------------------------------------------------------------------- /samples/vault/resources/vault-secret-password.txt: -------------------------------------------------------------------------------- 1 | password -------------------------------------------------------------------------------- /samples/vault/test-secret-copy-1.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | gather_facts: no 4 | 5 | tasks: 6 | - copy: 7 | src: resources/secret-file-for-copy.txt 8 | dest: /tmp/secret-file-for-copy-1-decrypted.txt 9 | -------------------------------------------------------------------------------- /samples/vault/test-secret-copy-2.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | gather_facts: no 4 | 5 | vars: 6 | spoiler: !vault | 7 | $ANSIBLE_VAULT;1.1;AES256 8 | 30306233623163393464333438313935306637313761303935326131633961373030643164373936 9 | 3034353464636161613432393763653530393066623738650a386462323663333962646231383666 10 | 30333963333136633933626133386536643538633232363162636565303963633934303130303131 11 | 3937303838633734630a653734623833666565363033306165383062346364313134346562636366 12 | 6133 13 | 14 | tasks: 15 | - copy: 16 | content: "{{ spoiler }}" 17 | dest: /tmp/secret-file-for-copy-2-decrypted.txt -------------------------------------------------------------------------------- /samples/vault/test-secret-file.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | gather_facts: no 4 | 5 | vars_files: 6 | - resources/secret-variables.yml 7 | 8 | tasks: 9 | - debug: var=spoiler 10 | -------------------------------------------------------------------------------- /samples/vault/test-secret-template.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | gather_facts: no 4 | 5 | vars: 6 | nonsecret: "Hello from playbook variable" 7 | 8 | tasks: 9 | - template: 10 | src: resources/secret-file-for-template.txt 11 | dest: /tmp/secret-file-for-template-decrypted.txt 12 | -------------------------------------------------------------------------------- /samples/vault/test-secret-variable.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | connection: local 3 | gather_facts: no 4 | 5 | vars: 6 | spoiler: !vault | 7 | $ANSIBLE_VAULT;1.1;AES256 8 | 30306233623163393464333438313935306637313761303935326131633961373030643164373936 9 | 3034353464636161613432393763653530393066623738650a386462323663333962646231383666 10 | 30333963333136633933626133386536643538633232363162636565303963633934303130303131 11 | 3937303838633734630a653734623833666565363033306165383062346364313134346562636366 12 | 6133 13 | 14 | tasks: 15 | - debug: var=spoiler 16 | -------------------------------------------------------------------------------- /trainings/day-1/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help 2 | 3 | help: 4 | @echo 'Usage:' 5 | @echo ' make ' 6 | @echo 7 | @echo 'Targets:' 8 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' 9 | @echo 10 | 11 | all: vagrant nginx tomcat 12 | 13 | vagrant: ## Vagrant Commands 14 | @echo "Vagrant Commands:" 15 | @echo " Start VM : vagrant up" 16 | @echo " Stop VM : vagrant halt" 17 | @echo " Destroy VM : vagrant destroy -f" 18 | @echo " Check VM Status : vagrant status" 19 | @echo " SSH Log In : vagrant ssh" 20 | @echo 21 | 22 | nginx: ## Nginx Installation Example 23 | @echo "Nginx Installation:" 24 | @echo " Run Playbook: ansible-playbook tasks/11.yml -i inventory03 -v" 25 | @echo " Check Service: http://192.168.56.21" 26 | @echo 27 | 28 | tomcat: tomcat-yum tomcat-src 29 | 30 | tomcat-yum: ## Tomcat Installation from YUM Example 31 | @echo "Tomcat Installation from YUM Example:" 32 | @echo " Run Playbook: ansible-playbook tasks/12.yml -i inventory03 -v" 33 | @echo " Check Service: http://192.168.56.21:8080" 34 | @echo 35 | 36 | tomcat-src: ## Tomcat Installation from SRC Example 37 | @echo "Tomcat Installation from SRC Example:" 38 | @echo " Run Playbook: ansible-playbook tasks/13.yml -i inventory03 -v" 39 | @echo " Check Service: http://192.168.56.21:8080" 40 | @echo -------------------------------------------------------------------------------- /trainings/day-1/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | config.vm.box = "centos/7" 3 | config.vm.hostname = "day1.ansible.cdp" 4 | config.vm.network :private_network, ip: "192.168.56.21" 5 | 6 | config.ssh.insert_key = false 7 | 8 | config.vm.provider "virtualbox" do |vb| 9 | # Virtual Machine Name 10 | vb.name = "ansible-day-1" 11 | # Display the VirtualBox GUI when booting the machine 12 | vb.gui = false 13 | # Customize the amount of memory on the VM: 14 | vb.memory = "512" 15 | end 16 | 17 | config.vm.provision "shell", inline: <<-SHELL 18 | yum install -y epel-release 19 | yum install -y python-pip 20 | pip install -U pip 21 | pip install -U ansible 22 | SHELL 23 | end -------------------------------------------------------------------------------- /trainings/day-1/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | 3 | # disable SSH key host checking 4 | host_key_checking = False 5 | 6 | 7 | # by default, if a task in a playbook does not include a name: field then 8 | # ansible-playbook will construct a header that includes the task's action but 9 | # not the task's args. This is a security feature because ansible cannot know 10 | # if the *module* considers an argument to be no_log at the time that the 11 | # header is printed. If your environment doesn't have a problem securing 12 | # stdout from ansible-playbook (or you have manually specified no_log in your 13 | # playbook on all of the tasks where you have secret information) then you can 14 | # safely set this to True to get more informative messages. 15 | display_args_to_stdout = True 16 | 17 | 18 | # When a playbook fails by default a .retry file will be created in playbook folder. 19 | # You can disable this feature by setting retry_files_enabled to False 20 | # and you can change the location of the files by setting retry_files_save_path 21 | retry_files_enabled = False 22 | #retry_files_save_path = ~/.ansible-retry -------------------------------------------------------------------------------- /trainings/day-1/inventory01: -------------------------------------------------------------------------------- 1 | [web] 2 | 192.168.56.21 3 | 4 | [app] 5 | 192.168.56.21 6 | -------------------------------------------------------------------------------- /trainings/day-1/inventory02: -------------------------------------------------------------------------------- 1 | [web] 2 | 192.168.56.21 ansible_connection=paramiko ansible_user=vagrant ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key 3 | 4 | [app] 5 | 192.168.56.21 ansible_connection=paramiko ansible_user=vagrant ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key 6 | -------------------------------------------------------------------------------- /trainings/day-1/inventory03: -------------------------------------------------------------------------------- 1 | [web] 2 | webserver01 ansible_host=192.168.56.21 ansible_connection=paramiko ansible_user=vagrant ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key 3 | 4 | [app] 5 | appserver01 ansible_host=192.168.56.21 ansible_connection=paramiko ansible_user=vagrant ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key 6 | -------------------------------------------------------------------------------- /trainings/day-1/tasks/12.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Deploy Tomcat 3 | hosts: app 4 | become: yes 5 | 6 | # Define Play Variables 7 | vars: 8 | jdk_release: "1.7.0" 9 | 10 | tasks: 11 | - name: Ensure OpenJDK Installed 12 | yum: name=java-{{ jdk_release }}-openjdk 13 | 14 | - name: Check Java Version 15 | shell: java -version 2>&1 | grep "{{ jdk_release }}" 16 | 17 | - name: Ensure Tomcat Installed 18 | yum: name=tomcat 19 | 20 | - name: Ensure Tomcat Webapps Package Installed 21 | yum: name=tomcat-webapps 22 | 23 | - name: Ensure Tomcat Service Running and Enabled 24 | service: name=tomcat state=started enabled=yes 25 | 26 | - name: Tomcat Sanity Checks 27 | hosts: app 28 | 29 | tasks: 30 | # We can't get variables from other Plays 31 | # It means, here, ansible doesn't know what is jdk_release 32 | # - name: Check that Java is Correct 33 | # shell: java -version | grep {{ jdk_release }} 34 | 35 | - name: Check if Tomcat Process Running 36 | shell: ps -eo cmd | grep -v grep | grep "tomcat" 37 | args: 38 | warn: false 39 | 40 | - name: Check if Tomcat Responds 200 41 | shell: curl -sL -w "%{http_code}" localhost:8080 -o /dev/null | grep 200 42 | args: 43 | warn: false 44 | 45 | - name: Check if It's really Tomcat 46 | shell: curl -s localhost:8080 | grep 'Apache Tomcat' >/dev/null 47 | args: 48 | warn: false -------------------------------------------------------------------------------- /trainings/day-1/tasks/files/nginx_home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Welcome to nginx! 5 | 12 | 13 | 14 |

 

15 |

Welcome to nginx!

16 |

17 | 18 | 19 | -------------------------------------------------------------------------------- /trainings/day-1/tasks/files/tomcat.service: -------------------------------------------------------------------------------- 1 | # Systemd unit file for default tomcat 2 | # 3 | # To create clones of this service: 4 | # DO NOTHING, use tomcat@.service instead. 5 | 6 | [Unit] 7 | Description=Apache Tomcat Web Application Container 8 | After=syslog.target network.target 9 | 10 | [Service] 11 | Type=forking 12 | ExecStart=/opt/apache/tomcat/current/bin/startup.sh 13 | ExecStop=/bin/kill -15 $MAINPID 14 | SuccessExitStatus=143 15 | User=tomcat 16 | Group=tomcat 17 | 18 | [Install] 19 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /trainings/day-1/tasks/templates/tomcat.service.j2: -------------------------------------------------------------------------------- 1 | # Systemd unit file for default tomcat 2 | # 3 | # To create clones of this service: 4 | # DO NOTHING, use tomcat@.service instead. 5 | 6 | [Unit] 7 | Description=Apache Tomcat Web Application Container 8 | After=syslog.target network.target 9 | 10 | [Service] 11 | Type=forking 12 | ExecStart={{ tomcat_home }}/current/bin/startup.sh 13 | ExecStop=/bin/kill -15 $MAINPID 14 | SuccessExitStatus=143 15 | User={{ tomcat_user }} 16 | Group={{ tomcat_group }} 17 | 18 | [Install] 19 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /trainings/day-2/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help 2 | 3 | help: 4 | @echo 'Usage:' 5 | @echo ' make ' 6 | @echo 7 | @echo 'Targets:' 8 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' 9 | @echo 10 | 11 | all: vagrant nginx java tomcat 12 | 13 | up: ## Start VM 14 | @vagrant up 15 | 16 | down: ## Stop VM 17 | @vagrant halt 18 | 19 | destroy: ## Destroy VM 20 | @vagrant destroy -f 21 | 22 | vagrant: ## Vagrant Commands 23 | @echo "Vagrant Commands:" 24 | @echo " Start VM : vagrant up" 25 | @echo " Stop VM : vagrant halt" 26 | @echo " Destroy VM : vagrant destroy -f" 27 | @echo " Check VM Status : vagrant status" 28 | @echo " SSH Log In : vagrant ssh" 29 | @echo 30 | 31 | nginx: ## Nginx Installation with Role Example 32 | @echo "Nginx Installation:" 33 | @echo " Run Playbook : ansible-playbook tasks/21.yml -v" 34 | @echo " Check Service : http://192.168.56.22" 35 | @echo 36 | 37 | java: ## Java Installation with Role Example 38 | @echo "Java Role PLaybook" 39 | @echo " Run Playbook : ansible-playbook tasks/22.yml -v" 40 | @echo " Check Facts : ansible appserver01 -m setup -a 'filter=ansible_local'" 41 | @echo 42 | 43 | tomcat: ## Tomcat Installation with Role Example 44 | @echo "Nginx&Tomcat Installation Example:" 45 | @echo " Run Playbook : ansible-playbook tasks/23.yml -v" 46 | @echo " Check Facts : ansible appserver01 -m setup -a 'filter=ansible_local'" 47 | @echo " Check Service : http://192.168.56.22:8080" 48 | @echo -------------------------------------------------------------------------------- /trainings/day-2/Readme.md: -------------------------------------------------------------------------------- 1 | ## Change Log 2 | 3 | - Introducing roles: Nginx, Java, Tomcat 4 | - Introducing handlers (in roles) 5 | - Introducing Facts usage 6 | - Introducing Registered Variables 7 | - Inventory file becomes more clean 8 | - Ansible config file contains reference to the project inventory file (to be used by default). It simplifies operations: just `ansible-playbook playbook.yml -v` enough now. 9 | 10 | ## Cheat sheet 11 | ``` 12 | # Start Local Engineering Environment 13 | $ vagrant up 14 | 15 | # Provision Nginx Example 16 | $ ansible-playbook tasks/21.yml -v 17 | 18 | # Provision Java Example 19 | $ ansible-playbook tasks/22.yml -v 20 | 21 | # Provision Tomcat Example 22 | $ ansible-playbook tasks/23.yml -v 23 | 24 | # Explore Installed Software and Configuration 25 | $ ansible app -m setup -a 'filter=ansible_local' 26 | 27 | # Stop VM 28 | $ vagrant halt 29 | 30 | # Destroy VM 31 | $ vagrant destroy -f 32 | ``` -------------------------------------------------------------------------------- /trainings/day-2/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | config.vm.box = "centos/7" 3 | config.vm.hostname = "day2.ansible.cdp" 4 | config.vm.network :private_network, ip: "192.168.56.22" 5 | 6 | config.ssh.insert_key = false 7 | 8 | config.vm.provider "virtualbox" do |vb| 9 | # Virtual Machine Name 10 | vb.name = "ansible-day-2" 11 | # Display the VirtualBox GUI when booting the machine 12 | vb.gui = false 13 | # Customize the amount of memory on the VM: 14 | vb.memory = "512" 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /trainings/day-2/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | # disable SSH key host checking 3 | host_key_checking = False 4 | 5 | 6 | # by default, if a task in a playbook does not include a name: field then 7 | # ansible-playbook will construct a header that includes the task's action but 8 | # not the task's args. This is a security feature because ansible cannot know 9 | # if the *module* considers an argument to be no_log at the time that the 10 | # header is printed. If your environment doesn't have a problem securing 11 | # stdout from ansible-playbook (or you have manually specified no_log in your 12 | # playbook on all of the tasks where you have secret information) then you can 13 | # safely set this to True to get more informative messages. 14 | display_args_to_stdout = True 15 | 16 | 17 | # When a playbook fails by default a .retry file will be created in ~/ 18 | # You can disable this feature by setting retry_files_enabled to False 19 | # and you can change the location of the files by setting retry_files_save_path 20 | retry_files_enabled = False 21 | #retry_files_save_path = ~/.ansible-retry 22 | 23 | 24 | # Default Inventory File for Current Project 25 | inventory = inventory 26 | -------------------------------------------------------------------------------- /trainings/day-2/inventory: -------------------------------------------------------------------------------- 1 | [web] 2 | webserver01 ansible_host=192.168.56.22 3 | 4 | [app] 5 | appserver01 ansible_host=192.168.56.22 6 | 7 | [farm:children] 8 | web 9 | app 10 | 11 | [farm:vars] 12 | ansible_connection=paramiko 13 | ansible_user=vagrant 14 | ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key 15 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/21.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Deploy Nginx 3 | hosts: web 4 | 5 | roles: 6 | - base 7 | - nginx -------------------------------------------------------------------------------- /trainings/day-2/tasks/22.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Deploy Java 3 | hosts: app 4 | 5 | roles: 6 | - base 7 | - java -------------------------------------------------------------------------------- /trainings/day-2/tasks/23.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Deploy Full Stack 3 | hosts: app 4 | 5 | roles: 6 | - { role: nginx } 7 | - { role: tomcat, tomcat_release: 8.5.29 } -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/base/README.md: -------------------------------------------------------------------------------- 1 | Base Role 2 | ========= 3 | 4 | The role can be used for provisioning common system configuration: 5 | - EPEL Repository 6 | - Python PIP Utility 7 | - Useful Python packages: requests 8 | - Ans to enable Ansible Facts.d directory 9 | 10 | Requirements 11 | ------------ 12 | 13 | The role has no requiremens 14 | 15 | Role Variables 16 | -------------- 17 | 18 | ``` 19 | pip_packages: 20 | - requests 21 | ``` 22 | 23 | Dependencies 24 | ------------ 25 | 26 | The role has no dependencies on other roles 27 | 28 | Example Playbook 29 | ---------------- 30 | 31 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 32 | 33 | - hosts: servers 34 | roles: 35 | - { role: base } 36 | 37 | License 38 | ------- 39 | 40 | BSD 41 | 42 | Author Information 43 | ------------------ 44 | 45 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 46 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/base/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for base 3 | pip_packages: 4 | - requests -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/base/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for base -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/base/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: your name 3 | description: your description 4 | company: your company (optional) 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 1.2 20 | 21 | # If this a Container Enabled role, provide the minimum Ansible Container version. 22 | # min_ansible_container_version: 23 | 24 | # Optionally specify the branch Galaxy will use when accessing the GitHub 25 | # repo for this role. During role install, if no tags are available, 26 | # Galaxy will use this branch. During import Galaxy will access files on 27 | # this branch. If Travis integration is configured, only notifications for this 28 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 29 | # (usually master) will be used. 30 | #github_branch: 31 | 32 | # 33 | # platforms is a list of platforms, and each platform has a name and a list of versions. 34 | # 35 | # platforms: 36 | # - name: Fedora 37 | # versions: 38 | # - all 39 | # - 25 40 | # - name: SomePlatform 41 | # versions: 42 | # - all 43 | # - 1.0 44 | # - 7 45 | # - 99.99 46 | 47 | galaxy_tags: [] 48 | # List tags for your role here, one per line. A tag is a keyword that describes 49 | # and categorizes the role. Users find roles by searching for tags. Be sure to 50 | # remove the '[]' above, if you add tags to this list. 51 | # 52 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 53 | # Maximum 20 tags per role. 54 | 55 | dependencies: [] 56 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 57 | # if you add dependencies to this list. -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/base/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Esure Ansible Facts Dir exists 3 | file: path=/etc/ansible/facts.d state=directory recurse=yes 4 | become: yes 5 | 6 | - name: Install Epel-release repo 7 | yum: name=epel-release 8 | become: yes 9 | 10 | - name: Install python-pip 11 | yum: name=python-pip 12 | become: yes 13 | 14 | - name: Install Python Dependencies 15 | pip: name={{ item }} 16 | with_items: 17 | - "{{ pip_packages }}" 18 | become: yes -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/base/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/base/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - base -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/base/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for base -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/java/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/java/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | jdk_release: "1.6.0" -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/java/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: save java details 3 | copy: 4 | content: > 5 | { 6 | "version": "{{ java_version.stdout }}", 7 | "build": "{{ java_build.stdout }}", 8 | "installed": "{{ ansible_date_time.iso8601 }}" 9 | } 10 | dest: /etc/ansible/facts.d/java.fact 11 | become: yes -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/java/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Siarhei Beliakou 3 | description: CDP Ansible Training 4 | company: EPAM 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 1.2 20 | 21 | # If this a Container Enabled role, provide the minimum Ansible Container version. 22 | # min_ansible_container_version: 23 | 24 | # Optionally specify the branch Galaxy will use when accessing the GitHub 25 | # repo for this role. During role install, if no tags are available, 26 | # Galaxy will use this branch. During import Galaxy will access files on 27 | # this branch. If Travis integration is configured, only notifications for this 28 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 29 | # (usually master) will be used. 30 | #github_branch: 31 | 32 | # 33 | # platforms is a list of platforms, and each platform has a name and a list of versions. 34 | # 35 | # platforms: 36 | # - name: Fedora 37 | # versions: 38 | # - all 39 | # - 25 40 | # - name: SomePlatform 41 | # versions: 42 | # - all 43 | # - 1.0 44 | # - 7 45 | # - 99.99 46 | 47 | galaxy_tags: [] 48 | # List tags for your role here, one per line. A tag is a keyword that describes 49 | # and categorizes the role. Users find roles by searching for tags. Be sure to 50 | # remove the '[]' above, if you add tags to this list. 51 | # 52 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 53 | # Maximum 20 tags per role. 54 | 55 | dependencies: [] 56 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 57 | # if you add dependencies to this list. -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/java/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure OpenJDK Installed 3 | yum: name=java-{{ jdk_release }}-openjdk 4 | become: yes 5 | notify: 6 | - save java details 7 | 8 | - name: Java Version 9 | shell: java -version 2>&1 | grep version | awk '{print $3}' | sed 's/[^0-9._]//g' 10 | register: java_version 11 | 12 | - name: Java Build 13 | shell: java -version 2>&1 | grep "Server VM .build" 14 | register: java_build 15 | 16 | - name: Ensure Facts Directory Exists 17 | file: 18 | path: /etc/ansible/facts.d 19 | recurse: yes 20 | state: directory 21 | become: yes -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/java/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/java/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - java -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/java/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for java -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/nginx/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/nginx/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for nginx -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/nginx/files/nginx_home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Welcome to nginx! 5 | 12 | 13 | 14 |

 

15 |

Welcome to nginx!

16 |

17 | 18 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/nginx/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: save nginx details 3 | copy: 4 | content: > 5 | { 6 | "version": "{{ nginx_version.stdout }}", 7 | "repository": { 8 | "file": "/etc/yum.repos.d/Nginx.repo", 9 | "name": "Nginx/{{ ansible_distribution_major_version }}/{{ ansible_userspace_architecture }}", 10 | "description": "Nginx Centos Repo" 11 | }, 12 | "configuration": { 13 | "TLS": "{{ nginx_tls.stdout }}", 14 | "configure_arguments": {{ nginx_configure_arguments.stdout_lines }} 15 | }, 16 | "installed": "{{ ansible_date_time.iso8601 }}" 17 | } 18 | dest: /etc/ansible/facts.d/nginx.fact 19 | become: yes 20 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/nginx/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Siarhei Beliakou 3 | description: CDP Ansible Training 4 | company: EPAM 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 1.2 20 | 21 | # If this a Container Enabled role, provide the minimum Ansible Container version. 22 | # min_ansible_container_version: 23 | 24 | # Optionally specify the branch Galaxy will use when accessing the GitHub 25 | # repo for this role. During role install, if no tags are available, 26 | # Galaxy will use this branch. During import Galaxy will access files on 27 | # this branch. If Travis integration is configured, only notifications for this 28 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 29 | # (usually master) will be used. 30 | #github_branch: 31 | 32 | # 33 | # platforms is a list of platforms, and each platform has a name and a list of versions. 34 | # 35 | # platforms: 36 | # - name: Fedora 37 | # versions: 38 | # - all 39 | # - 25 40 | # - name: SomePlatform 41 | # versions: 42 | # - all 43 | # - 1.0 44 | # - 7 45 | # - 99.99 46 | 47 | galaxy_tags: [] 48 | # List tags for your role here, one per line. A tag is a keyword that describes 49 | # and categorizes the role. Users find roles by searching for tags. Be sure to 50 | # remove the '[]' above, if you add tags to this list. 51 | # 52 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 53 | # Maximum 20 tags per role. 54 | 55 | dependencies: [] 56 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 57 | # if you add dependencies to this list. -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/nginx/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add Nginx Repository 3 | yum_repository: 4 | name: Nginx 5 | description: Nginx Centos Repo 6 | baseurl: http://nginx.org/packages/centos/$releasever/$basearch/ 7 | gpgcheck: no 8 | enabled: yes 9 | become: yes 10 | 11 | - name: Ensure Nginx Installed 12 | yum: name=nginx 13 | notify: 14 | - save nginx details 15 | become: yes 16 | 17 | # Update Default Home Page 18 | - name: Deploy Customized Home Page 19 | copy: 20 | src: nginx_home.html 21 | dest: /usr/share/nginx/html/index.html 22 | become: yes 23 | 24 | - name: Ensure Nginx Service Running and Enabled 25 | service: name=nginx state=started enabled=yes 26 | become: yes 27 | 28 | - name: Get Nginx Version 29 | shell: /usr/sbin/nginx -v 2>&1 | awk -F'/' '{print $2}' 30 | register: nginx_version 31 | 32 | - name: Get Nginx TLS Settings 33 | shell: /usr/sbin/nginx -V 2>&1 | grep TLS 34 | register: nginx_tls 35 | 36 | - name: Get Nginx Configured Settings 37 | shell: /usr/sbin/nginx -V 2>&1 | grep 'configure arguments' | sed 's/ --/\n--/g' | sed '1d' 38 | register: nginx_configure_arguments 39 | 40 | - name: Ensure Nginx Service Running and Enabled 41 | service: name=nginx state=started enabled=yes 42 | become: yes 43 | 44 | - name: Check if Nginx Process Running 45 | shell: ps -ef | grep -v grep | grep "nginx. master process" 46 | args: 47 | warn: false 48 | 49 | - name: Check if Nginx Responds 200 50 | shell: curl -sL -w "%{http_code}" localhost -o /dev/null | grep 200 51 | args: 52 | warn: false 53 | 54 | - name: Check if it's really Nginx 55 | shell: curl -sIL localhost | grep "^Server. nginx" 56 | args: 57 | warn: false -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/nginx/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/nginx/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - nginx -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/nginx/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for nginx -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | tomcat_release: "7.0.85" 3 | tomcat_user: tomcat 4 | tomcat_group: tomcat 5 | tomcat_user_id: 950 6 | tomcat_group_id: 950 7 | tomcat_home: /opt/apache/tomcat 8 | 9 | tomcat_admin_enabled: false 10 | tomcat_admin: admin 11 | tomcat_admin_password: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters') }}" -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: systemd daemon reload 3 | systemd: daemon_reload=yes 4 | become: yes 5 | 6 | - name: restart tomcat 7 | systemd: state=started name=tomcat 8 | become: yes 9 | 10 | - name: save tomcat details 11 | copy: 12 | content: > 13 | { 14 | "release": "{{ tomcat_release }}", 15 | "user": { 16 | "name": "{{ tomcat_user }}", 17 | "id": "{{ tomcat_user_id }}" 18 | }, 19 | "group": { 20 | "name": "{{ tomcat_group }}", 21 | "id": "{{ tomcat_group_id }}" 22 | }, 23 | "tomcat_home": "{{ tomcat_home }}", 24 | "catalina_home": "{{ tomcat_home }}/apache-tomcat-{{ tomcat_release }}", 25 | "catalina_home_link": "{{ tomcat_home }}/current", 26 | "tomcat_download_url": "{{ tomcat_url }}", 27 | "installed": "{{ ansible_date_time.iso8601 }}" 28 | } 29 | dest: /etc/ansible/facts.d/tomcat.fact 30 | become: yes 31 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Siarhei Beliakou 3 | description: CDP Ansible Training 4 | company: EPAM 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 1.2 20 | 21 | # If this a Container Enabled role, provide the minimum Ansible Container version. 22 | # min_ansible_container_version: 23 | 24 | # Optionally specify the branch Galaxy will use when accessing the GitHub 25 | # repo for this role. During role install, if no tags are available, 26 | # Galaxy will use this branch. During import Galaxy will access files on 27 | # this branch. If Travis integration is configured, only notifications for this 28 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 29 | # (usually master) will be used. 30 | #github_branch: 31 | 32 | # 33 | # platforms is a list of platforms, and each platform has a name and a list of versions. 34 | # 35 | # platforms: 36 | # - name: Fedora 37 | # versions: 38 | # - all 39 | # - 25 40 | # - name: SomePlatform 41 | # versions: 42 | # - all 43 | # - 1.0 44 | # - 7 45 | # - 99.99 46 | 47 | galaxy_tags: [] 48 | # List tags for your role here, one per line. A tag is a keyword that describes 49 | # and categorizes the role. Users find roles by searching for tags. Be sure to 50 | # remove the '[]' above, if you add tags to this list. 51 | # 52 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 53 | # Maximum 20 tags per role. 54 | 55 | dependencies: 56 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 57 | # if you add dependencies to this list. 58 | - role: java 59 | jdk_release: "{{ tomcat_java_version }}" -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/templates/context.xml.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/templates/tomcat-users.xml.j2: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/templates/tomcat.service.j2: -------------------------------------------------------------------------------- 1 | # Systemd unit file for default tomcat 2 | # 3 | # To create clones of this service: 4 | # DO NOTHING, use tomcat@.service instead. 5 | 6 | [Unit] 7 | Description=Apache Tomcat Web Application Container 8 | After=syslog.target network.target 9 | 10 | [Service] 11 | Type=forking 12 | ExecStart={{ tomcat_home }}/current/bin/startup.sh 13 | ExecStop=/bin/kill -15 $MAINPID 14 | SuccessExitStatus=143 15 | User={{ tomcat_user }} 16 | Group={{ tomcat_group }} 17 | 18 | [Install] 19 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - tomcat -------------------------------------------------------------------------------- /trainings/day-2/tasks/roles/tomcat/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | tomcat_url: "http://www-eu.apache.org/dist/tomcat/tomcat-{{ tomcat_release.split('.')[0] }}/v{{ tomcat_release }}/bin/apache-tomcat-{{ tomcat_release }}.tar.gz" 3 | tomcat_java_version: "1.{{ tomcat_release.split('.')[0] }}.0" -------------------------------------------------------------------------------- /trainings/day-3/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help 2 | 3 | help: 4 | @echo 'Usage:' 5 | @echo ' make ' 6 | @echo 7 | @echo 'Targets:' 8 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' 9 | @echo 10 | 11 | loops: ## Ansible Loops Examples 12 | @echo "Ansible Loops Examples:" 13 | @echo " https://github.com/sbeliakou/ansible-examples/tree/develop/samples/loops" 14 | @echo 15 | 16 | conditions: ## Ansible Conditions Examples 17 | @echo "Ansible Conditions Examples:" 18 | @echo " https://github.com/sbeliakou/ansible-examples/tree/develop/samples/conditions" 19 | @echo 20 | 21 | filters: ## Ansible Jinja2 Filters Examples 22 | @echo "Ansible Jinja2 Filters Examples:" 23 | @echo " https://github.com/sbeliakou/ansible-examples/tree/develop/samples/filters" 24 | @echo 25 | @echo "Custom Filters:" 26 | @echo " $ ansible-playbook tasks/mongodb_selector_filter/mongodb_url_select.yml" 27 | @echo " $ ansible-playbook tasks/corporate_emails/corporate_email.yml" 28 | 29 | 30 | modules: ## Testing Custom Modules 31 | @echo "Testing Modules" 32 | @echo " $ ansible localhost -m custom_module_bash.sh" 33 | @echo " $ ansible localhost -m custom_module_args_bash -a 'msg=\"hello from my bash module\"'" 34 | @echo " $ ansible localhost -m custom_module_python" 35 | @echo " $ ansible localhost -m custom_module_args_python -a 'msg='\"hello from my python module\"'" 36 | @echo 37 | 38 | # deploment: ## Dynamic Inventory 39 | # @echo " 40 | # $ ansible-playbook tasks/vagrant_management/vagrant.yml -v \\ 41 | # -e vagrantfile=./ \\ 42 | # -e @tasks/vagrant_management/deployment.json \\ 43 | # -e application_war=$(pwd)/sample.war 44 | # " -------------------------------------------------------------------------------- /trainings/day-3/Readme.md: -------------------------------------------------------------------------------- 1 | ## Environement Configuration 2 | - [Vargantfile](Vagrantfile) 3 | - [Ansible Inventory File](inventory) 4 | - [Ansible Configuration File](ansible.cfg) 5 | 6 | ## Change Log 7 | 8 | - [X] Introducing Custom Filter: MongoDB SRC URL selector 9 | - [X] Introducing Custom Filter: Corporate Email Composer 10 | - [X] Introducing Custom Module: Vagrant management (python) 11 | - [X] Introducing Module Tomcat WAR Deployment 12 | - [X] Introducing Playbook to Spin up Environment, Install Tomcat Server, Deploy WAR file 13 | - [X] Introducing add_host Module 14 | - [X] Introducing Dynamic Inventory Script 15 | - [X] Ansible config file contains reference to the folder with custom modules. It simplifies operations, don't need to add `-M path/` or set `ANSIBLE_LIBRARY` env variable 16 | 17 | ## Cheat sheet 18 | ``` 19 | # Start Local Engineering Environment 20 | $ vagrant up 21 | 22 | # Figure out what Mongo Archive will be downloaded 23 | $ ansible-playbook tasks/mongodb_selector_filter/mongodb_url_select.yml 24 | 25 | # Stop VM 26 | $ vagrant halt 27 | 28 | # Destroy VM 29 | $ vagrant destroy -f 30 | 31 | # Generate a List of emails by Users List 32 | $ ansible-playbook tasks/corporate_emails/corporate_email.yml 33 | 34 | # Testing Modules 35 | $ ansible localhost -m custom_module_bash.sh 36 | $ ansible localhost -m custom_module_args_bash -a 'msg="hello from my bash module"' 37 | $ ansible localhost -m custom_module_python 38 | $ ansible localhost -m custom_module_args_python -a 'msg="hello from my python module"' 39 | 40 | # Testing Modules in Playbook 41 | $ ansible-playbook tasks/custom_modules/testing_modules.yml -v 42 | 43 | # Tomcat Stack 44 | $ ansible-playbook tasks/vagrant_management/vagrant.yml -v \ 45 | -e vagrantfile=./ \ 46 | -e @tasks/vagrant_management/deployment.json \ 47 | -e application_war=$(pwd)/sample.war 48 | 49 | ``` 50 | 51 | ## Examples Specification 52 | 53 | ### 1. Custom Filter: MongoDB SRC URL selector 54 | ### 2. Custom Filter: Corporate Email Composer 55 | ### 3. Custom Module: Vagrant management (python, bash) 56 | ### 4. Module Tomcat WAR Deployment 57 | ### 5. Playbook to Spin up Environment, Install Tomcat Server, Deploy WAR file -------------------------------------------------------------------------------- /trainings/day-3/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | config.vm.box = "centos/7" 3 | config.vm.hostname = "day3.ansible.cdp" 4 | config.vm.network :private_network, ip: "192.168.56.23" 5 | 6 | config.ssh.insert_key = false 7 | 8 | config.vm.provider "virtualbox" do |vb| 9 | # Virtual Machine Name 10 | vb.name = "ansible-day-3" 11 | # Display the VirtualBox GUI when booting the machine 12 | vb.gui = false 13 | # Customize the amount of memory on the VM: 14 | vb.memory = "512" 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /trainings/day-3/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | # disable SSH key host checking 3 | host_key_checking = False 4 | 5 | # by default, if a task in a playbook does not include a name: field then 6 | # ansible-playbook will construct a header that includes the task's action but 7 | # not the task's args. This is a security feature because ansible cannot know 8 | # if the *module* considers an argument to be no_log at the time that the 9 | # header is printed. If your environment doesn't have a problem securing 10 | # stdout from ansible-playbook (or you have manually specified no_log in your 11 | # playbook on all of the tasks where you have secret information) then you can 12 | # safely set this to True to get more informative messages. 13 | display_args_to_stdout = True 14 | 15 | # When a playbook fails by default a .retry file will be created in ~/ 16 | # You can disable this feature by setting retry_files_enabled to False 17 | # and you can change the location of the files by setting retry_files_save_path 18 | retry_files_enabled = False 19 | #retry_files_save_path = ~/.ansible-retry 20 | 21 | 22 | # Default Inventory File for Current Project 23 | inventory = inventory 24 | 25 | # Default Folfer with Modules 26 | library = tasks/custom_modules/library/ 27 | 28 | # additional paths to search for roles in, colon separated 29 | roles_path = ../day-2/tasks/roles/ -------------------------------------------------------------------------------- /trainings/day-3/inventory: -------------------------------------------------------------------------------- 1 | [app] 2 | server ansible_host=192.168.56.23 3 | 4 | [app:vars] 5 | ansible_connection=paramiko 6 | ansible_user=vagrant 7 | ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key 8 | -------------------------------------------------------------------------------- /trainings/day-3/sample.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/trainings/day-3/sample.war -------------------------------------------------------------------------------- /trainings/day-3/tasks/corporate_emails/corporate_email.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | 3 | vars: 4 | namesdb: 5 | - { name: Siarhei, surname: Beliakou } 6 | - { name: James, surname: Vicari } 7 | - { name: Phillip, surname: Haslett } 8 | - { name: Veronika, surname: Hettlinger } 9 | 10 | tasks: 11 | - debug: msg={{ namesdb | email | sort }} 12 | - debug: msg={{ namesdb | email('customer.net') | sort }} -------------------------------------------------------------------------------- /trainings/day-3/tasks/corporate_emails/filter_plugins/filters.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | from functools import partial 5 | import types 6 | 7 | from ansible import errors 8 | 9 | 10 | def email(arg, suffix="epam.com"): 11 | import re 12 | 13 | result = [] 14 | for item in arg: 15 | result.append("{}_{}@{}".format(item['name'], item['surname'], suffix)) 16 | 17 | return result 18 | 19 | 20 | class FilterModule(object): 21 | def filters(self): 22 | return { 23 | 'email': email 24 | } -------------------------------------------------------------------------------- /trainings/day-3/tasks/corporate_emails/output.txt: -------------------------------------------------------------------------------- 1 | PLAY [localhost] *************************************************************** 2 | 3 | TASK [Gathering Facts gather_subset=all, gather_timeout=10] ******************** 4 | 5 | TASK [debug msg={{ namesdb | email | sort }}] ********************************** 6 | ok: [localhost] => { 7 | "msg": [ 8 | "James_Vicari@epam.com", 9 | "Phillip_Haslett@epam.com", 10 | "Siarhei_Beliakou@epam.com", 11 | "Veronika_Hettlinger@epam.com" 12 | ] 13 | } 14 | 15 | TASK [debug msg={{ namesdb | email('customer.net') | sort }}] ****************** 16 | "msg": [ 17 | "James_Vicari@customer.net", 18 | "Phillip_Haslett@customer.net", 19 | "Siarhei_Beliakou@customer.net", 20 | "Veronika_Hettlinger@customer.net" 21 | ] 22 | } 23 | 24 | PLAY RECAP ********************************************************************* 25 | localhost : ok=3 changed=0 unreachable=0 failed=0 -------------------------------------------------------------------------------- /trainings/day-3/tasks/custom_modules/library/custom_module_args_bash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # --- 4 | # Simple Ansible Module with Args 5 | # 6 | # - simple_module_bash: 7 | # msg: Hello from module 8 | # 9 | # Ansible passes arguments to the module as file 10 | # ./module_name file_with_argumets 11 | 12 | [ -f "$1" ] && source $1 13 | 14 | if [ -z "${msg}" ]; then 15 | printf '{"failed": true, "msg": "Missing required arguments: msg"}' 16 | exit 1 17 | fi 18 | 19 | cat << EOF 20 | { 21 | "changed": true, 22 | "msg": "${msg}" 23 | } 24 | EOF 25 | 26 | exit 0 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /trainings/day-3/tasks/custom_modules/library/custom_module_args_python.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | 5 | DOCUMENTATION = ''' 6 | --- 7 | module: custom_module_args_python 8 | version_added: historical 9 | short_description: Simple Ansible Module written on Python 10 | options: 11 | msg: 12 | version_added: "1.0" 13 | description: 14 | - "Message to be returned by module" 15 | required: true 16 | default: 'None' 17 | description: 18 | - This is an example module which returns custom message 19 | author: 20 | - "Siarhei Beliakou" 21 | ''' 22 | 23 | EXAMPLES = """ 24 | # Standalone mode launch. 25 | ansible localhost -c local -m custom_module_args_python -a msg='message' 26 | 27 | - custom_module_args_python: 28 | msg: "message" 29 | 30 | """ 31 | 32 | from ansible.module_utils.basic import * 33 | 34 | def main(): 35 | module = AnsibleModule( 36 | argument_spec = dict( 37 | msg = dict(required=True, type='str') 38 | ) 39 | ) 40 | 41 | msg = module.params["msg"] 42 | 43 | results = {} 44 | 45 | results.update({ 46 | "changed": True, 47 | "msg": msg 48 | }) 49 | 50 | module.exit_json(**results) 51 | 52 | # include magic from lib/ansible/module_common.py 53 | #<> 54 | main() 55 | -------------------------------------------------------------------------------- /trainings/day-3/tasks/custom_modules/library/custom_module_bash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # --- 4 | # Simple Ansible Module without Args 5 | # 6 | # - simple_module_bash: 7 | # msg: Hello from module 8 | 9 | cat << EOF 10 | { 11 | "time": "$(date +'%Y-%m-%d %T')" 12 | } 13 | EOF 14 | 15 | 16 | -------------------------------------------------------------------------------- /trainings/day-3/tasks/custom_modules/library/custom_module_python.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | DOCUMENTATION = ''' 4 | --- 5 | module: custom_module_python 6 | version_added: historical 7 | short_description: Simple Ansible Module written on Python 8 | 9 | description: 10 | - This is an example module which returns current date 11 | author: 12 | - "Siarhei Beliakou" 13 | ''' 14 | 15 | EXAMPLES = """ 16 | # Standalone mode launch. 17 | ansible localhost -c local -m custom_module_python 18 | 19 | - custom_module_python: 20 | 21 | """ 22 | 23 | import datetime 24 | import json 25 | 26 | date = str(datetime.datetime.now()) 27 | print json.dumps({ 28 | "time": date 29 | }) 30 | 31 | 32 | -------------------------------------------------------------------------------- /trainings/day-3/tasks/custom_modules/test.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: no 3 | 4 | tasks: 5 | - name: module library/custom_module_args_python 6 | custom_module_args_python: 7 | msg: Hello from python module 8 | -------------------------------------------------------------------------------- /trainings/day-3/tasks/custom_modules/testing_modules.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: no 3 | 4 | tasks: 5 | - name: module library/custom_module_bash.sh 6 | custom_module_bash: 7 | 8 | - name: module library/custom_module_python.py 9 | custom_module_python: 10 | 11 | - name: module library/custom_module_args_bash.sh 12 | custom_module_args_bash: 13 | msg: Hello from bash module 14 | 15 | - name: module library/custom_module_args_python.sh 16 | custom_module_args_python: 17 | msg: Hello from python module -------------------------------------------------------------------------------- /trainings/day-3/tasks/inventory_script/Readme.md: -------------------------------------------------------------------------------- 1 | ## Testing Inventory Script 2 | ``` 3 | $ ./vagrant_inventory.py --list 4 | { 5 | "vagrant": { 6 | "hosts": [ 7 | "default" 8 | ], 9 | "vars": { 10 | "ansible_user": "vagrant", 11 | "ansible_private_key_file": "~/.vagrant.d/insecure_private_key" 12 | } 13 | }, 14 | "_meta": { 15 | "hostvars": { 16 | "default": { 17 | "ansible_port": "2200", 18 | "ansible_host": "127.0.0.1" 19 | } 20 | } 21 | } 22 | } 23 | ``` 24 | 25 | ``` 26 | $ ./vagrant_inventory.py --host default 27 | { 28 | "ansible_port": "2200", 29 | "ansible_ssh_user": "vagrant", 30 | "ansible_ssh_private_key_file": "~/.vagrant.d/insecure_private_key", 31 | "ansible_host": "127.0.0.1" 32 | } 33 | ``` 34 | 35 | ## Playbook 36 | ```yaml 37 | - hosts: vagrant 38 | 39 | tasks: 40 | - debug: var=inventory_hostname 41 | ``` 42 | 43 | ## Testing Playbook 44 | 45 | ``` 46 | $ ansible-playbook test-vagrant-inventory.yml -i vagrant_inventory.py 47 | ``` 48 | ``` 49 | PLAY [vagrant] ***************************************************************** 50 | 51 | TASK [Gathering Facts gather_subset=all, gather_timeout=10] ******************** 52 | ok: [default] 53 | 54 | TASK [debug var=inventory_hostname] ******************************************** 55 | ok: [default] => { 56 | "inventory_hostname": "default" 57 | } 58 | 59 | PLAY RECAP ********************************************************************* 60 | default : ok=2 changed=0 unreachable=0 failed=0 61 | ``` -------------------------------------------------------------------------------- /trainings/day-3/tasks/inventory_script/test-vagrant-inventory.yml: -------------------------------------------------------------------------------- 1 | - hosts: vagrant 2 | 3 | tasks: 4 | - debug: var=inventory_hostname 5 | 6 | -------------------------------------------------------------------------------- /trainings/day-3/tasks/inventory_script/vagrant_inventory.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import argparse 4 | import os 5 | import vagrant 6 | import json 7 | 8 | # Requirements: 9 | # pip install python-vagrant 10 | 11 | def main(): 12 | parser = argparse.ArgumentParser(description="Parse list parameter") 13 | parser.add_argument("--list", default=False, action="store_true" , help="Flag to do list hosts") 14 | parser.add_argument("--host", default="", action="store" , help="Flag to get host") 15 | args = parser.parse_args() 16 | 17 | stack = vagrant.Vagrant(os.getcwd()) 18 | current = stack.conf() 19 | 20 | if stack.status()[0].state == "running": 21 | if(args.host): 22 | if(args.host == current["Host"] ): 23 | print json.dumps({ 24 | "ansible_host": current["HostName"], 25 | "ansible_port": current["Port"], 26 | "ansible_user": current["User"], 27 | "ansible_ssh_private_key_file": current["IdentityFile"] 28 | }, indent=4) 29 | else: 30 | print {} 31 | 32 | if(args.list): 33 | print json.dumps({ 34 | "vagrant" : { 35 | "hosts" : [ 36 | current["Host"] 37 | ], 38 | "vars": { 39 | "ansible_user": current["User"], 40 | "ansible_ssh_private_key_file": current["IdentityFile"] 41 | } 42 | }, 43 | "_meta": { 44 | "hostvars": { 45 | current["Host"]: { 46 | "ansible_host": current["HostName"], 47 | "ansible_port": current["Port"] 48 | } 49 | } 50 | } 51 | }, indent=4) 52 | else: 53 | print {} 54 | 55 | if __name__ == '__main__': 56 | main() -------------------------------------------------------------------------------- /trainings/day-3/tasks/mongodb_selector_filter/filter_plugins/filters.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, division, print_function) 2 | __metaclass__ = type 3 | 4 | from functools import partial 5 | import types 6 | 7 | from ansible import errors 8 | 9 | 10 | def get_mongo_src(arg, os_name, os_version, mongo_version): 11 | import re 12 | 13 | os_name = os_name.lower() 14 | if os_name == "centos": 15 | os_name = "rhel" 16 | 17 | if os_name == "redhat": 18 | os_name = "rhel" 19 | 20 | if os_name == "linuxmint": 21 | os_name = "ubuntu" 22 | 23 | for item in arg: 24 | if re.match('.*' + os_name + os_version + '.*', item, re.M|re.I) and re.match('.*' + mongo_version + '.*', item, re.M|re.I): 25 | return item 26 | 27 | return "nothing found" 28 | 29 | 30 | class FilterModule(object): 31 | def filters(self): 32 | return { 33 | 'get_mongo_src': get_mongo_src 34 | } -------------------------------------------------------------------------------- /trainings/day-3/tasks/mongodb_selector_filter/mongodb_url_select.yml: -------------------------------------------------------------------------------- 1 | - hosts: server 2 | 3 | vars: 4 | # https://www.mongodb.org/dl/linux/x86_64 5 | # http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel70-v3.2-latest.tgz 6 | mongo_src: 7 | - mongodb-linux-x86_64-rhel64-3.0.14 8 | - mongodb-linux-x86_64-rhel64-3.2.11 9 | - mongodb-linux-x86_64-rhel70-3.0.14 10 | - mongodb-linux-x86_64-rhel70-3.2.17 11 | - mongodb-linux-x86_64-rhel70-3.4.13 12 | - mongodb-linux-x86_64-rhel70-3.6.3 13 | - mongodb-linux-x86_64-rhel70-3.7.2 14 | - mongodb-linux-x86_64-ubuntu1604-3.4.12 15 | - mongodb-linux-x86_64-ubuntu1604-3.4.13 16 | - mongodb-linux-x86_64-ubuntu1604-3.6.3 17 | - mongodb-linux-x86_64-ubuntu1604-3.7.2 18 | - mongodb-linux-x86_64-debian81-3.4.13 19 | - mongodb-linux-x86_64-debian81-3.2.19 20 | - mongodb-linux-x86_64-debian81-3.7.2 21 | 22 | mongo_version: "3.7" 23 | 24 | system_info: |- 25 | OS Name: "{{ ansible_distribution }}" 26 | OS Family: '{{ ansible_os_family }}' 27 | Version Major Release: {{ ansible_distribution_major_version }} 28 | 29 | mongo_url_base: http://downloads.mongodb.org/linux 30 | mongo_url: "{{ mongo_url_base }}/{{ mongo_src | get_mongo_src(ansible_distribution, ansible_distribution_major_version, mongo_version) }}.tgz" 31 | 32 | tasks: 33 | - debug: var=system_info.split('\n') 34 | - debug: var=mongo_url 35 | 36 | - fail: msg="Sorry, there's no mongo distributive found" 37 | when: mongo_url | search('nothing found') -------------------------------------------------------------------------------- /trainings/day-3/tasks/vagrant_management/deployment.json: -------------------------------------------------------------------------------- 1 | { 2 | "tomcat_admin": "admin", 3 | "tomcat_admin_password": "password", 4 | "tomcat_war_context": "/samplewar" 5 | } -------------------------------------------------------------------------------- /trainings/day-3/tasks/vagrant_management/vagrant.yml: -------------------------------------------------------------------------------- 1 | - name: Start VM 2 | hosts: localhost 3 | 4 | tasks: 5 | - name: Ensure VM is running 6 | vagrant_box: 7 | path: "{{ vagrantfile | mandatory }}" 8 | state: running 9 | register: vm 10 | 11 | - name: Update Inventory with newly created host 12 | add_host: 13 | name: playground 14 | hostname: "{{ vm.Host }}" 15 | ansible_host: "{{ vm.HostName }}" 16 | ansible_port: "{{ vm.Port }}" 17 | ansible_connection: "paramiko" 18 | ansible_user: "{{ vm.User }}" 19 | ansible_ssh_private_key_file: "{{ vm.IdentityFile }}" 20 | external_ip: "{{ vm.ip_adresses[1] }}" 21 | 22 | - name: Provision Playground VM 23 | hosts: playground 24 | 25 | vars: 26 | system_info: |- 27 | Distributive: {{ ansible_distribution }} 28 | Family: {{ ansible_distribution_file_variety }} 29 | Version: {{ ansible_distribution_version }} 30 | 31 | pre_tasks: 32 | - debug: msg={{ system_info.split('\n') }} 33 | 34 | roles: 35 | - role: base 36 | - role: nginx 37 | - role: tomcat 38 | tomcat_release: 8.5.29 39 | tomcat_admin_enabled: yes 40 | tomcat_admin: '{{ tomcat_admin }}' 41 | tomcat_admin_password: '{{ tomcat_admin_password }}' 42 | 43 | - name: Deploy WAR 44 | hosts: localhost 45 | gather_facts: no 46 | 47 | tasks: 48 | - name: Deploy WAR 49 | deploy_war: 50 | url: "http://{{ hostvars['playground'].external_ip }}:8080" 51 | username: "{{ tomcat_admin }}" 52 | password: "{{ tomcat_admin_password }}" 53 | context: "{{ tomcat_war_context }}" 54 | src: "{{ application_war }}" 55 | register: deployment 56 | 57 | - name: Check deployment status 58 | uri: 59 | url: "{{ deployment.application_url }}" 60 | register: status 61 | failed_when: "'OK' not in status.msg" 62 | 63 | - name: Cleanup VM 64 | hosts: localhost 65 | 66 | vars: 67 | cleanup: no 68 | 69 | tasks: 70 | - name: Cleanup 71 | vagrant_box: 72 | path: "{{ vagrantfile | mandatory }}" 73 | state: destroyed 74 | when: cleanup 75 | -------------------------------------------------------------------------------- /trainings/day-4/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help 2 | 3 | help: 4 | @echo 'Usage:' 5 | @echo ' make ' 6 | @echo 7 | @echo 'Targets:' 8 | @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' 9 | @echo 10 | 11 | all: tags templates blocks callback 12 | 13 | tags: ## Tags Usage Example 14 | @echo "Tags Usage Examples:" 15 | @echo " - List Playbook Tags:" 16 | @echo " ansible-playbook tasks/tags/vagrant.yml --list-tags" 17 | @echo 18 | @echo " - Create VM, Provision VM, Deploy WAR, Destroy VM:" 19 | @echo " ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json" 20 | @echo 21 | @echo " - Create VM, Provision VM and Deploy WAR:" 22 | @echo " ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json --skip-tags=cleanup" 23 | @echo 24 | @echo " - Provision VM": 25 | @echo " ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json --tags=provision" 26 | @echo 27 | @echo " - Deploy WAR (only):" 28 | @echo " ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json --tags=deploy" 29 | @echo 30 | @echo " - Destroy VM:" 31 | @echo " ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json --tags=cleanup" 32 | @echo 33 | 34 | blocks: ## Blocks Usage Examples 35 | @echo "Rescue / Error Handling" 36 | @echo " ansible-playbook tasks/blocks/rescue.yml -v" 37 | @echo 38 | 39 | callback: ## Callback Plugin Usage Example 40 | @echo "Testing Custom Callback Plugin:" 41 | @echo " ANSIBLE_CONFIG=tasks/callback/ansible.cfg ansible-playbook tasks/callback/callback-test.yml -v" 42 | @echo 43 | 44 | templates: ## Templates examples 45 | @echo "Testing Ansible Templates:" 46 | @echo " ansible-playbook tasks/templates/testing_templates.yml --tags=example0; cat /tmp/result-by-example-0.conf" 47 | @echo " ansible-playbook tasks/templates/testing_templates.yml --tags=example1; cat /tmp/result-by-example-1.conf" 48 | @echo " ansible-playbook tasks/templates/testing_templates.yml --tags=example2; cat /tmp/result-by-example-2.conf" 49 | @echo " ansible-playbook tasks/templates/testing_templates.yml --tags=example3; cat /tmp/result-by-example-3.conf" 50 | @echo 51 | -------------------------------------------------------------------------------- /trainings/day-4/Readme.md: -------------------------------------------------------------------------------- 1 | ## Change Log 2 | 3 | - [X] Introducing Tags 4 | - [X] Introducing Custom Callback Plugin 5 | - [X] Introducing Blocks: Rescue Management and Error Handling 6 | - [ ] Introducing Include* Directives 7 | 8 | 9 | ## Tags Examples 10 | ``` 11 | #List Playbook Tags: 12 | $ ansible-playbook tasks/tags/vagrant.yml --list-tags 13 | #Create VM, Provision VM, Deploy WAR, Destroy VM: 14 | $ ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json 15 | #Create VM, Provision VM and Deploy WAR: 16 | $ ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json --skip-tags=cleanup 17 | #Provision VM: 18 | $ ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json --tags=provision 19 | #Deploy WAR (only): 20 | $ ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json --tags=deploy 21 | #Destroy VM: 22 | $ ansible-playbook tasks/tags/vagrant.yml -v -e @tasks/tags/deployment.json --tags=cleanup 23 | 24 | # Rescue/Error Example 25 | $ ansible-playbook tasks/blocks/rescue.yml -v 26 | 27 | # Custom Callback Example 28 | $ ANSIBLE_CONFIG=tasks/callback/ansible.cfg ansible-playbook tasks/callback/callback-test.yml -v 29 | ``` -------------------------------------------------------------------------------- /trainings/day-4/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | config.vm.box = "centos/7" 3 | config.vm.hostname = "day4.ansible.cdp" 4 | config.vm.network :private_network, ip: "192.168.56.24" 5 | 6 | config.ssh.insert_key = false 7 | 8 | config.vm.provider "virtualbox" do |vb| 9 | # Virtual Machine Name 10 | vb.name = "ansible-day-4" 11 | # Display the VirtualBox GUI when booting the machine 12 | vb.gui = false 13 | # Customize the amount of memory on the VM: 14 | vb.memory = "512" 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /trainings/day-4/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | # disable SSH key host checking 3 | host_key_checking = False 4 | 5 | # by default, if a task in a playbook does not include a name: field then 6 | # ansible-playbook will construct a header that includes the task's action but 7 | # not the task's args. This is a security feature because ansible cannot know 8 | # if the *module* considers an argument to be no_log at the time that the 9 | # header is printed. If your environment doesn't have a problem securing 10 | # stdout from ansible-playbook (or you have manually specified no_log in your 11 | # playbook on all of the tasks where you have secret information) then you can 12 | # safely set this to True to get more informative messages. 13 | display_args_to_stdout = True 14 | 15 | # When a playbook fails by default a .retry file will be created in ~/ 16 | # You can disable this feature by setting retry_files_enabled to False 17 | # and you can change the location of the files by setting retry_files_save_path 18 | retry_files_enabled = False 19 | #retry_files_save_path = ~/.ansible-retry 20 | 21 | # Default Folfer with Modules 22 | library = ../day-3/tasks/custom_modules/library/ 23 | 24 | # additional paths to search for roles in, colon separated 25 | roles_path = ../day-2/tasks/roles/ 26 | 27 | 28 | ansible_managed = This file is managed by Ansible.%n 29 | Training: CDP. Ansible by S.Beliakou, Module 4 30 | template: {file} 31 | date: %Y-%m-%d %H:%M:%S 32 | user: {uid} 33 | -------------------------------------------------------------------------------- /trainings/day-4/tasks/blocks/rescue.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | 3 | tasks: 4 | - block: 5 | - name: Create temporary directory 6 | file: 7 | path: /tmp/deploy 8 | state: directory 9 | 10 | - name: Russian roulette deployment 11 | debug: msg="Deploying..." 12 | failed_when: 2|random == 1 13 | 14 | - name: Deployed Awards 15 | debug: msg="We've deployed!" 16 | 17 | rescue: 18 | - name: Notify about the failure 19 | debug: msg="Deployment failed! Tell everyone!" 20 | 21 | - name: Rollback any changes 22 | debug: msg="Rolling back..." 23 | 24 | always: 25 | - name: Remove temporary directory 26 | file: 27 | path: /tmp/deploy 28 | state: absent 29 | 30 | - name: Will I have a chance to play? 31 | debug: msg="I will do the best" -------------------------------------------------------------------------------- /trainings/day-4/tasks/callback/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | callback_whitelist = demo 3 | stdout_callback = demo 4 | 5 | retry_files_enabled = False -------------------------------------------------------------------------------- /trainings/day-4/tasks/callback/callback-test.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | 3 | tasks: 4 | - name: Greetings 5 | shell: echo Hello 6 | 7 | - name: Skip 8 | debug: msg="Hello again" 9 | when: False 10 | 11 | - name: Fail and continue 12 | fail: msg="What can go wrong?" 13 | ignore_errors: True 14 | 15 | - name: Fail 16 | fail: msg="OH Nooooo--" 17 | 18 | - name: Never run 19 | debug: msg="I will never run :(" 20 | 21 | -------------------------------------------------------------------------------- /trainings/day-4/tasks/tags/deployment.json: -------------------------------------------------------------------------------- 1 | { 2 | "tomcat_admin": "admin", 3 | "tomcat_admin_password": "password", 4 | "tomcat_war_context": "/samplewar", 5 | "application_war": "sample.war" 6 | } -------------------------------------------------------------------------------- /trainings/day-4/tasks/tags/sample.war: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbeliakou/ansible-examples/c3c4578af87ff996fb671fad84de2e85b55fbaf3/trainings/day-4/tasks/tags/sample.war -------------------------------------------------------------------------------- /trainings/day-4/tasks/tags/vagrant.yml: -------------------------------------------------------------------------------- 1 | - name: Start VM 2 | hosts: localhost 3 | gather_facts: no 4 | tags: 5 | - always 6 | 7 | tasks: 8 | - name: Ensure VM is running 9 | vagrant_box: 10 | path: "{{ vagrantfile | default(playbook_dir) }}" 11 | state: running 12 | register: vm 13 | 14 | - name: Update Inventory with newly created host 15 | add_host: 16 | name: playground 17 | hostname: "{{ vm.Host }}" 18 | ansible_host: "{{ vm.HostName }}" 19 | ansible_port: "{{ vm.Port }}" 20 | ansible_connection: "paramiko" 21 | ansible_user: "{{ vm.User }}" 22 | ansible_ssh_private_key_file: "{{ vm.IdentityFile }}" 23 | external_ip: "{{ vm.ip_adresses[1] }}" 24 | 25 | - name: Provision Playground VM 26 | hosts: playground 27 | tags: 28 | - provision 29 | 30 | vars: 31 | system_info: |- 32 | Distributive: {{ ansible_distribution }} 33 | Family: {{ ansible_distribution_file_variety }} 34 | Version: {{ ansible_distribution_version }} 35 | 36 | pre_tasks: 37 | - debug: msg={{ system_info.split('\n') }} 38 | 39 | roles: 40 | - role: base 41 | - role: nginx 42 | - role: tomcat 43 | tomcat_release: 8.5.29 44 | tomcat_admin_enabled: yes 45 | tomcat_admin: '{{ tomcat_admin }}' 46 | tomcat_admin_password: '{{ tomcat_admin_password }}' 47 | 48 | - name: Deploy WAR 49 | hosts: localhost 50 | gather_facts: no 51 | tags: 52 | - deploy 53 | 54 | tasks: 55 | - name: Deploy WAR 56 | deploy_war: 57 | url: "http://{{ hostvars['playground'].external_ip }}:8080" 58 | username: "{{ tomcat_admin }}" 59 | password: "{{ tomcat_admin_password }}" 60 | context: "{{ tomcat_war_context }}" 61 | src: "{{ application_war }}" 62 | register: deployment 63 | 64 | - name: Check deployment status 65 | uri: 66 | url: "{{ deployment.application_url }}" 67 | register: status 68 | failed_when: "'OK' not in status.msg" 69 | 70 | - name: Cleanup VM 71 | hosts: localhost 72 | tags: 73 | - cleanup 74 | 75 | tasks: 76 | - name: Cleanup 77 | vagrant_box: 78 | path: "{{ vagrantfile | default(playbook_dir) }}" 79 | state: destroyed 80 | -------------------------------------------------------------------------------- /trainings/day-4/tasks/templates/templates/template-example-0.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | List of Domains: 4 | {% for domain in domains %} 5 | - {{ domain }} 6 | {% endfor %} 7 | 8 | In One Line: {% for domain in domains %}{{ domain }} {% endfor %} 9 | 10 | Search Items with "1": 11 | {% for domain in domains %} 12 | {% if domain | search('1')%} 13 | - {{ domain }} 14 | {% endif %} 15 | {% endfor %} 16 | 17 | Search Items with "2" or "4": 18 | {% for domain in domains %} 19 | {% if domain | search('2') or domain | search('4') %} 20 | - {{ domain }} 21 | {% endif %} 22 | {% endfor %} 23 | 24 | -------------------------------------------------------------------------------- /trainings/day-4/tasks/templates/templates/template-example-1.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | {{ "Example: Templates/1" | comment }} 4 | 5 | http { 6 | index index.html; 7 | 8 | {% for domain_name in ['domain1.example.com', 'domain2.example.com'] %} 9 | server { 10 | server_name {{ domain_name }}; 11 | access_log logs/{{ domain_name }}.access.log main; 12 | 13 | root /var/www/{{ domain_name }}.com/htdocs; 14 | } 15 | {% endfor %} 16 | 17 | } 18 | -------------------------------------------------------------------------------- /trainings/day-4/tasks/templates/templates/template-example-2.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | {{ "Example: Templates/2" | comment }} 4 | 5 | http { 6 | index index.html; 7 | 8 | {% for domain_name in domains %} 9 | server { 10 | server_name {{ domain_name }}; 11 | access_log logs/{{ domain_name }}.access.log main; 12 | 13 | root /var/www/{{ domain_name }}.com/htdocs; 14 | } 15 | 16 | {% endfor %} 17 | 18 | } 19 | -------------------------------------------------------------------------------- /trainings/day-4/tasks/templates/templates/template-example-3.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | {{ "Example: Templates/3" | comment }} 4 | 5 | http { 6 | index index.html; 7 | 8 | {% for domain_name in domains %} 9 | server { 10 | {% if domain_name == domains[0] %} 11 | listen 80 default_server; 12 | server_name _; 13 | {% else %} 14 | server_name {{ domain_name }}; 15 | {% endif %} 16 | access_log logs/{{ domain_name }}{% if domain_name == domains[0] %}-default{% endif %}.access.log main; 17 | 18 | root /var/www/{{ domain_name }}{% if domain_name == domains[0] %}-default{% endif %}.com/htdocs; 19 | } 20 | 21 | {% endfor %} 22 | 23 | } 24 | -------------------------------------------------------------------------------- /trainings/day-4/tasks/templates/testing_templates.yml: -------------------------------------------------------------------------------- 1 | - name: Example 0 2 | hosts: localhost 3 | gather_facts: no 4 | tags: 5 | - example0 6 | 7 | vars: 8 | domains: 9 | - domain1.example.com 10 | - domain2.example.com 11 | - domain3.example.com 12 | - domain4.example.com 13 | 14 | tasks: 15 | - template: 16 | src: template-example-0.j2 17 | dest: /tmp/result-by-example-0.conf 18 | 19 | - name: Example 1, Slides 26-27 20 | hosts: localhost 21 | gather_facts: no 22 | tags: 23 | - example1 24 | 25 | tasks: 26 | - template: 27 | src: template-example-1.j2 28 | dest: /tmp/result-by-example-1.conf 29 | 30 | 31 | - name: Example 2, Slide 28 32 | hosts: localhost 33 | gather_facts: no 34 | tags: 35 | - example2 36 | 37 | vars: 38 | domains: 39 | - domain1.example.com 40 | - domain2.example.com 41 | 42 | tasks: 43 | - template: 44 | src: template-example-2.j2 45 | dest: /tmp/result-by-example-2.conf 46 | 47 | 48 | - name: Example 3, Slides 29-30 49 | hosts: localhost 50 | gather_facts: no 51 | tags: 52 | - example3 53 | 54 | vars: 55 | domains: 56 | - domain1.example.com 57 | - domain2.example.com 58 | 59 | tasks: 60 | - template: 61 | src: template-example-3.j2 62 | dest: /tmp/result-by-example-3.conf 63 | -------------------------------------------------------------------------------- /trainings/day-5/Readme.md: -------------------------------------------------------------------------------- 1 | ## Using Ansible Vault 2 | 3 | Password Files: 4 | ``` 5 | 6 | ``` 7 | 8 | Ensrypting secrets: 9 | ``` 10 | $ ansible-vault encrypt_string --vault-id dev@a_password_file 'Dev Stack Secret' 11 | !vault | 12 | $ANSIBLE_VAULT;1.2;AES256;dev 13 | 66363164613536343663356639383363386264303662643332643761653333323638373237623638 14 | 3037353732393836346134643364396165636433373235640a393539363530626261386236376230 15 | 64313739393537363638323362373863653566303266653061396336303736376230363239333639 16 | 3463336365653864630a623232393861653066333031643562623837333063613334636639343464 17 | 33383234393662353630303331636536663165646432373863393331633064613963 18 | Encryption successful 19 | 20 | $ ansible-vault encrypt_string --vault-id prod@b_password_file 'Prod Stack Secret' 21 | !vault | 22 | $ANSIBLE_VAULT;1.2;AES256;prod 23 | 31613838353831343631353338383665393036643364313433353630636363643030376262653239 24 | 3265343231383736633730656534663531313166363233320a316462396666643965373266663830 25 | 36633066363634303032366532656161326431613831663931356137393838386134323139653963 26 | 3331366462313566640a366365656236643062333362373337366466383138353565663662636136 27 | 34303539373964623237613235663263613932653966383534386335333137656138 28 | Encryption successful 29 | ``` 30 | 31 | ``` 32 | $ ansible-playbook test.yml --vault-id a_password_file --vault-id b_password_file 33 | 34 | PLAY [localhost] ************************************************************************* 35 | 36 | TASK [debug] ***************************************************************************** 37 | ok: [localhost] => { 38 | "spoiler1": "String to be ENCRYPTED" 39 | } 40 | 41 | TASK [debug] ***************************************************************************** 42 | ok: [localhost] => { 43 | "spoiler2": "Dev Stack Secret" 44 | } 45 | 46 | TASK [debug] ***************************************************************************** 47 | ok: [localhost] => { 48 | "spoiler3": "Prod Stack Secret" 49 | } 50 | 51 | PLAY RECAP ******************************************************************************* 52 | localhost : ok=3 changed=0 unreachable=0 failed=0 53 | ``` -------------------------------------------------------------------------------- /trainings/day-5/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | config.vm.box = "centos/7" 3 | config.vm.hostname = "day5.ansible.cdp" 4 | config.vm.network :private_network, ip: "192.168.56.25" 5 | 6 | config.ssh.insert_key = false 7 | 8 | config.vm.provider "virtualbox" do |vb| 9 | # Virtual Machine Name 10 | vb.name = "ansible-day-5" 11 | # Display the VirtualBox GUI when booting the machine 12 | vb.gui = false 13 | # Customize the amount of memory on the VM: 14 | vb.memory = "512" 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /trainings/day-5/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | # disable SSH key host checking 3 | host_key_checking = False 4 | 5 | # by default, if a task in a playbook does not include a name: field then 6 | # ansible-playbook will construct a header that includes the task's action but 7 | # not the task's args. This is a security feature because ansible cannot know 8 | # if the *module* considers an argument to be no_log at the time that the 9 | # header is printed. If your environment doesn't have a problem securing 10 | # stdout from ansible-playbook (or you have manually specified no_log in your 11 | # playbook on all of the tasks where you have secret information) then you can 12 | # safely set this to True to get more informative messages. 13 | display_args_to_stdout = True 14 | 15 | # When a playbook fails by default a .retry file will be created in ~/ 16 | # You can disable this feature by setting retry_files_enabled to False 17 | # and you can change the location of the files by setting retry_files_save_path 18 | retry_files_enabled = False 19 | #retry_files_save_path = ~/.ansible-retry 20 | 21 | ansible_managed = This file is managed by Ansible.%n 22 | Training: CDP. Ansible by S.Beliakou, Module 5 23 | template: {file} 24 | date: %Y-%m-%d %H:%M:%S 25 | user: {uid} 26 | 27 | verbosity = 1 28 | -------------------------------------------------------------------------------- /trainings/day-5/inventory: -------------------------------------------------------------------------------- 1 | [pull] 2 | 192.168.56.25 3 | 4 | [pull:vars] 5 | ansible_connection=paramiko 6 | ansible_user=vagrant 7 | ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/Readme.md: -------------------------------------------------------------------------------- 1 | # Packer Demo 2 | 3 | ## 1 Packer Basics: 4 | 5 | ### 1.1 Packer Configuration file 6 | 7 | Main Configuration in JSON (example): 8 | ``` 9 | { 10 | "variables": { 11 | "variable1": "default value", 12 | "variable2": "default value" 13 | }, 14 | "builders": { 15 | [ 16 | { 17 | "type": "builder-type", 18 | ... 19 | } 20 | ] 21 | }, 22 | "post-processors": [ 23 | [ 24 | { 25 | "type": "post-processor type", 26 | ... 27 | } 28 | ] 29 | ] 30 | } 31 | ``` 32 | 33 | ### 1.2 Packer Commands 34 | ``` 35 | # Build Image 36 | $ packer build << packer_template.json >> 37 | 38 | # Build Image with Custom Variables 39 | $ packer build -var variable1=some_value << packer_template.json >> 40 | $ packer build -var-file=file_with_vars << packer_template.json >> 41 | 42 | # Restrict Builders (builder names/types: foo, bar, baz) 43 | $ packer build -only=foo,bar,baz << packer_template.json >> 44 | 45 | # Validate Template 46 | $ packer validate << packer_template.json >> 47 | ``` 48 | 49 | ### 1.3 More Details: 50 | - [Installing Packer](https://www.packer.io/intro/getting-started/install.html) 51 | - [Variables](https://www.packer.io/docs/templates/user-variables.html) 52 | - [Template Builders](https://www.packer.io/docs/templates/builders.html) 53 | - [Template Post-Processors](https://www.packer.io/docs/templates/post-processors.html) 54 | - [Builder: `docker`](https://www.packer.io/docs/builders/docker.html) 55 | - [Provisioner: `shell`](https://www.packer.io/docs/provisioners/shell.html) 56 | - [Post-Processor: `docker-tag`](https://www.packer.io/docs/post-processors/docker-tag.html) 57 | - [Post-Processor: `docker-push`](https://www.packer.io/docs/post-processors/docker-push.html) 58 | 59 | ## 2 Project Structure 60 | 61 | Packer Configuration: [example.json](example.json) 62 | Ansible Playbook: [playbook.yml](playbook.yml) 63 | Asnible Roles: [roles/nginx](roles/nginx) 64 | 65 | ## 3 Building Image 66 | 67 | ``` 68 | $ packer build example.json 69 | ``` 70 | 71 | ## 4 Spinning Up a Container from the Image 72 | 73 | ``` 74 | $ docker run -d --privileged -P 80:80 centos-built-by-packer-with-ansible:2018-11-05-11-53-34 75 | ``` -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "builders": [{ 3 | "type": "docker", 4 | "image": "sbeliakou/centos", 5 | "commit": true, 6 | "changes": [ 7 | "EXPOSE 80" 8 | ], 9 | "privileged": true, 10 | "run_command": [ 11 | "-dit", 12 | "{{.Image}}", 13 | "/usr/sbin/init" 14 | ] 15 | }], 16 | 17 | "provisioners": [ 18 | { 19 | "type": "ansible", 20 | "user": "root", 21 | "playbook_file": "provision.yml", 22 | "extra_arguments": [ 23 | "-vv" 24 | ], 25 | "ansible_env_vars": [ 26 | "PYTHONUNBUFFERED=1", 27 | "ANSIBLE_FORCE_COLOR=1", 28 | "ANSIBLE_STDOUT_CALLBACK=debug", 29 | "ANSIBLE_CALLBACK_WHITELIST=profile_tasks", 30 | "ANSIBLE_HOST_KEY_CHECKING=False", 31 | "ANSIBLE_RETRY_FILES_ENABLED=False", 32 | "ANSIBLE_LOCAL_TEMP=$HOME/.ansible/tmp", 33 | "ANSIBLE_REMOTE_TEMP=$HOME/.ansible/tmp" 34 | ] 35 | } 36 | ], 37 | 38 | "post-processors": [ 39 | [ 40 | { 41 | "type": "docker-tag", 42 | "repository": "centos-built-by-packer-with-ansible", 43 | "tag": "{{ isotime \"2006-01-02-03-04-05\" }}" 44 | } 45 | ] 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/provision.yml: -------------------------------------------------------------------------------- 1 | - hosts: all 2 | 3 | pre_tasks: 4 | - yum: name=epel-release 5 | 6 | roles: 7 | - role: nginx 8 | nginx_mode: node -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for nginx 3 | 4 | nginx_mode: 5 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for nginx 3 | 4 | - name: Restart Nginx 5 | systemd: name=nginx state=restarted 6 | become: yes 7 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: your name 3 | description: your description 4 | company: your company (optional) 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 1.2 20 | 21 | # If this a Container Enabled role, provide the minimum Ansible Container version. 22 | # min_ansible_container_version: 23 | 24 | # Optionally specify the branch Galaxy will use when accessing the GitHub 25 | # repo for this role. During role install, if no tags are available, 26 | # Galaxy will use this branch. During import Galaxy will access files on 27 | # this branch. If Travis integration is configured, only notifications for this 28 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 29 | # (usually master) will be used. 30 | #github_branch: 31 | 32 | # 33 | # platforms is a list of platforms, and each platform has a name and a list of versions. 34 | # 35 | # platforms: 36 | # - name: Fedora 37 | # versions: 38 | # - all 39 | # - 25 40 | # - name: SomePlatform 41 | # versions: 42 | # - all 43 | # - 1.0 44 | # - 7 45 | # - 99.99 46 | 47 | galaxy_tags: [] 48 | # List tags for your role here, one per line. A tag is a keyword that describes 49 | # and categorizes the role. Users find roles by searching for tags. Be sure to 50 | # remove the '[]' above, if you add tags to this list. 51 | # 52 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 53 | # Maximum 20 tags per role. 54 | 55 | dependencies: [] 56 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 57 | # if you add dependencies to this list. -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/tasks/lb.yml: -------------------------------------------------------------------------------- 1 | - name: Copy Nginx Config 2 | template: 3 | src: nginx-lb.conf.j2 4 | dest: /etc/nginx/nginx.conf 5 | notify: Restart Nginx 6 | become: yes 7 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for nginx 3 | 4 | - name: Install Nginx 5 | package: name=nginx 6 | become: yes 7 | 8 | - name: Get Nginx Version 9 | shell: /usr/sbin/nginx -V 2>&1 | grep 'nginx version' | awk -F/ '{print $2}' 10 | register: nginx_version 11 | changed_when: no 12 | 13 | - name: Create Facts Folder 14 | file: 15 | path: /etc/ansible/facts.d 16 | state: directory 17 | become: yes 18 | 19 | - name: Save Fact 20 | copy: 21 | content: 22 | { 23 | "version": "{{ nginx_version.stdout }}" 24 | } 25 | dest: /etc/ansible/facts.d/nginx.fact 26 | become: yes 27 | 28 | - name: Start Nginx 29 | systemd: name=nginx state=started enabled=yes 30 | become: yes 31 | 32 | - include_tasks: node.yml 33 | when: "nginx_mode == 'node'" 34 | 35 | - include_tasks: lb.yml 36 | when: "nginx_mode == 'lb'" 37 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/tasks/node.yml: -------------------------------------------------------------------------------- 1 | - name: Copy Custom Page 2 | template: 3 | src: index.html.j2 4 | # dest: "{{ nginx_root }}/index.html" 5 | dest: "{{ nginx_root[ansible_distribution] }}/index.html" 6 | become: yes 7 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/templates/index.html.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Welcome to nginx! 5 | 12 | 13 | 14 |

 

15 |

Baked by Packer

16 |

Provisioned by Ansible

17 |

18 | 19 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/templates/nginx-lb.conf.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | user nginx; 4 | worker_processes auto; 5 | error_log /var/log/nginx/error.log; 6 | pid /run/nginx.pid; 7 | 8 | # Load dynamic modules. See /usr/share/nginx/README.dynamic. 9 | include /usr/share/nginx/modules/*.conf; 10 | 11 | events { 12 | worker_connections 1024; 13 | } 14 | 15 | http { 16 | upstream nodes { 17 | {% for host in groups['nodes'] %} 18 | server {{ hostvars[host].ansible_default_ipv4.address }}; 19 | {% endfor %} 20 | } 21 | 22 | server { 23 | listen 80; 24 | 25 | location / { 26 | proxy_pass http://nodes; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - nginx -------------------------------------------------------------------------------- /trainings/day-5/tasks/packer/roles/nginx/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for nginx 3 | 4 | nginx_root: 5 | Ubuntu: /var/www/html/ 6 | CentOS: /usr/share/nginx/html/ 7 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/ansible-pull-configure.yml: -------------------------------------------------------------------------------- 1 | - hosts: all 2 | gather_facts: no 3 | 4 | tasks: 5 | - name: Installing SUDO 6 | raw: yum install -y sudo which creates=/bin/sudo 7 | register: yum_install 8 | changed_when: "'Nothing to do' not in yum_install.stdout" 9 | 10 | - hosts: all 11 | become: yes 12 | 13 | vars: 14 | # schedule is fed directly to cron 15 | schedule: '* * * * *' 16 | 17 | # User to run ansible-pull as from cron 18 | cron_user: root 19 | cron_group: root 20 | 21 | # File that ansible will use for logs 22 | logfile: /var/log/ansible-pull.log 23 | 24 | # Directory to where repository will be cloned 25 | workdir: /var/lib/ansible/local 26 | 27 | # Repository and Branch to check out 28 | repo_url: git://github.com/sbeliakou/ansible-examples.git 29 | repo_branch: develop 30 | 31 | # Playbook to apply on the host 32 | playbook: "trainings/day-5/tasks/pull/local.yml" 33 | 34 | tasks: 35 | - name: install yum-utils 36 | yum: name=yum-utils 37 | 38 | - name: install packages 39 | yum: name={{ item }} 40 | with_items: 41 | - epel-release 42 | - git 43 | - cronie 44 | 45 | - name: install python pip 46 | yum: name=python-pip 47 | 48 | - name: ensure cron is running 49 | systemd: name=crond state=started 50 | 51 | - name: Install ansible 52 | pip: name=ansible 53 | 54 | - name: Create local directory to work from 55 | file: 56 | path: "{{ workdir }}" 57 | state: directory 58 | owner: "{{ cron_user }}" 59 | group: "{{ cron_group }}" 60 | mode: 0751 61 | 62 | - name: Create Ansible Pull Cron Job 63 | cron: 64 | name: "Ansible Pull Job" 65 | job: >- 66 | ANSIBLE_CONFIG={{ workdir }}/trainings/day-5/ansible.cfg 67 | ANSIBLE_LOG_PATH={{ logfile }} 68 | ansible-pull 69 | -U {{ repo_url }} 70 | -C {{ repo_branch }} 71 | -d {{ workdir }} 72 | {{ playbook }} >/dev/null 2>&1 73 | user: "{{ cron_user }}" 74 | 75 | - name: Create logrotate entry for ansible-pull.log 76 | template: 77 | src: templates/etc_logrotate.d_ansible-pull.j2 78 | dest: /etc/logrotate.d/ansible-pull 79 | owner: "{{ cron_user }}" 80 | group: "{{ cron_group }}" 81 | mode: 0644 82 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | centos: 5 | image: "sbeliakou/trainings:centos-node-2" 6 | volumes: 7 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 8 | cap_add: 9 | - SYS_ADMIN 10 | expose: 11 | - 80 12 | ports: 13 | - 127.0.0.1:2200:22/tcp 14 | - 127.0.0.1:80:80/tcp -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/local.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: yes 3 | 4 | roles: 5 | - role: nginx 6 | nginx_mode: node 7 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | A brief description of the role goes here. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required. 10 | 11 | Role Variables 12 | -------------- 13 | 14 | A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. 15 | 16 | Dependencies 17 | ------------ 18 | 19 | A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles. 20 | 21 | Example Playbook 22 | ---------------- 23 | 24 | Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too: 25 | 26 | - hosts: servers 27 | roles: 28 | - { role: username.rolename, x: 42 } 29 | 30 | License 31 | ------- 32 | 33 | BSD 34 | 35 | Author Information 36 | ------------------ 37 | 38 | An optional section for the role authors to include contact information, or a website (HTML is not allowed). 39 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for nginx 3 | 4 | nginx_mode: 5 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for nginx 3 | 4 | - name: Restart Nginx 5 | systemd: name=nginx state=restarted 6 | become: yes 7 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: your name 3 | description: your description 4 | company: your company (optional) 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 1.2 20 | 21 | # If this a Container Enabled role, provide the minimum Ansible Container version. 22 | # min_ansible_container_version: 23 | 24 | # Optionally specify the branch Galaxy will use when accessing the GitHub 25 | # repo for this role. During role install, if no tags are available, 26 | # Galaxy will use this branch. During import Galaxy will access files on 27 | # this branch. If Travis integration is configured, only notifications for this 28 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 29 | # (usually master) will be used. 30 | #github_branch: 31 | 32 | # 33 | # platforms is a list of platforms, and each platform has a name and a list of versions. 34 | # 35 | # platforms: 36 | # - name: Fedora 37 | # versions: 38 | # - all 39 | # - 25 40 | # - name: SomePlatform 41 | # versions: 42 | # - all 43 | # - 1.0 44 | # - 7 45 | # - 99.99 46 | 47 | galaxy_tags: [] 48 | # List tags for your role here, one per line. A tag is a keyword that describes 49 | # and categorizes the role. Users find roles by searching for tags. Be sure to 50 | # remove the '[]' above, if you add tags to this list. 51 | # 52 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 53 | # Maximum 20 tags per role. 54 | 55 | dependencies: [] 56 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 57 | # if you add dependencies to this list. -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/tasks/lb.yml: -------------------------------------------------------------------------------- 1 | - name: Copy Nginx Config 2 | template: 3 | src: nginx-lb.conf.j2 4 | dest: /etc/nginx/nginx.conf 5 | notify: Restart Nginx 6 | become: yes 7 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for nginx 3 | 4 | - name: Install Nginx 5 | package: name=nginx 6 | become: yes 7 | 8 | - name: Get Nginx Version 9 | shell: /usr/sbin/nginx -V 2>&1 | grep 'nginx version' | awk -F/ '{print $2}' 10 | register: nginx_version 11 | changed_when: no 12 | 13 | - name: Create Facts Folder 14 | file: 15 | path: /etc/ansible/facts.d 16 | state: directory 17 | become: yes 18 | 19 | - name: Save Fact 20 | copy: 21 | content: 22 | { 23 | "version": "{{ nginx_version.stdout }}" 24 | } 25 | dest: /etc/ansible/facts.d/nginx.fact 26 | become: yes 27 | 28 | - name: Start Nginx 29 | systemd: name=nginx state=started enabled=yes 30 | become: yes 31 | 32 | - include_tasks: node.yml 33 | when: "nginx_mode == 'node'" 34 | 35 | - include_tasks: lb.yml 36 | when: "nginx_mode == 'lb'" 37 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/tasks/node.yml: -------------------------------------------------------------------------------- 1 | - name: Copy Custom Page 2 | template: 3 | src: index.html.j2 4 | # dest: "{{ nginx_root }}/index.html" 5 | dest: "{{ nginx_root[ansible_distribution] }}/index.html" 6 | become: yes 7 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/templates/index.html.j2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Welcome to nginx! 5 | 6 | 13 | 14 | 15 |

 

16 |

Welcome to nginx!

17 |

18 |

Maintainer: Siarhei Beliakou

19 | 20 | 21 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/templates/nginx-lb.conf.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | user nginx; 4 | worker_processes auto; 5 | error_log /var/log/nginx/error.log; 6 | pid /run/nginx.pid; 7 | 8 | # Load dynamic modules. See /usr/share/nginx/README.dynamic. 9 | include /usr/share/nginx/modules/*.conf; 10 | 11 | events { 12 | worker_connections 1024; 13 | } 14 | 15 | http { 16 | upstream nodes { 17 | {% for host in groups['nodes'] %} 18 | server {{ hostvars[host].ansible_default_ipv4.address }}; 19 | {% endfor %} 20 | } 21 | 22 | server { 23 | listen 80; 24 | 25 | location / { 26 | proxy_pass http://nodes; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - nginx -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/roles/nginx/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for nginx 3 | 4 | nginx_root: 5 | Ubuntu: /var/www/html/ 6 | CentOS: /usr/share/nginx/html/ 7 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/pull/templates/etc_logrotate.d_ansible-pull.j2: -------------------------------------------------------------------------------- 1 | {{ logfile }} { 2 | rotate 7 3 | daily 4 | compress 5 | missingok 6 | notifempty 7 | } 8 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/vault/Readme.md: -------------------------------------------------------------------------------- 1 | ## Using Ansible Vault 2 | 3 | Password Files: 4 | ``` 5 | $ cat a_password_file 6 | secret phrase A 7 | 8 | $ cat b_password_file 9 | secret phrase B 10 | ``` 11 | 12 | Ensrypting secrets: 13 | ``` 14 | $ ansible-vault encrypt_string --vault-id dev@a_password_file 'Dev Stack Secret' 15 | !vault | 16 | $ANSIBLE_VAULT;1.2;AES256;dev 17 | 66363164613536343663356639383363386264303662643332643761653333323638373237623638 18 | 3037353732393836346134643364396165636433373235640a393539363530626261386236376230 19 | 64313739393537363638323362373863653566303266653061396336303736376230363239333639 20 | 3463336365653864630a623232393861653066333031643562623837333063613334636639343464 21 | 33383234393662353630303331636536663165646432373863393331633064613963 22 | Encryption successful 23 | 24 | $ ansible-vault encrypt_string --vault-id prod@b_password_file 'Prod Stack Secret' 25 | !vault | 26 | $ANSIBLE_VAULT;1.2;AES256;prod 27 | 31613838353831343631353338383665393036643364313433353630636363643030376262653239 28 | 3265343231383736633730656534663531313166363233320a316462396666643965373266663830 29 | 36633066363634303032366532656161326431613831663931356137393838386134323139653963 30 | 3331366462313566640a366365656236643062333362373337366466383138353565663662636136 31 | 34303539373964623237613235663263613932653966383534386335333137656138 32 | Encryption successful 33 | ``` 34 | 35 | ``` 36 | $ ansible-playbook test.yml --vault-id a_password_file --vault-id b_password_file 37 | 38 | PLAY [localhost] ************************************************************************* 39 | 40 | TASK [debug] ***************************************************************************** 41 | ok: [localhost] => { 42 | "spoiler1": "String to be ENCRYPTED" 43 | } 44 | 45 | TASK [debug] ***************************************************************************** 46 | ok: [localhost] => { 47 | "spoiler2": "Dev Stack Secret" 48 | } 49 | 50 | TASK [debug] ***************************************************************************** 51 | ok: [localhost] => { 52 | "spoiler3": "Prod Stack Secret" 53 | } 54 | 55 | PLAY RECAP ******************************************************************************* 56 | localhost : ok=3 changed=0 unreachable=0 failed=0 57 | ``` 58 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/vault/a_password_file: -------------------------------------------------------------------------------- 1 | secret phrase A 2 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/vault/b_password_file: -------------------------------------------------------------------------------- 1 | big big secret 2 | -------------------------------------------------------------------------------- /trainings/day-5/tasks/vault/test.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | gather_facts: no 3 | 4 | vars: 5 | spoiler1: !vault | 6 | $ANSIBLE_VAULT;1.1;AES256 7 | 31336236363338313261326332666663366262386334353534666539623730313765313165623063 8 | 6638393337356336373261326338663834313163623064620a306465623131656565656163626666 9 | 65323039353364373938373665363037383264343637383661386263333330353937616335663764 10 | 3934356235623531630a613165383530653830643566353737663964663834653266333131653362 11 | 36666437306561623962383466313234393062346164363033646335613534353534 12 | 13 | spoiler2: !vault | 14 | $ANSIBLE_VAULT;1.2;AES256;dev 15 | 66363164613536343663356639383363386264303662643332643761653333323638373237623638 16 | 3037353732393836346134643364396165636433373235640a393539363530626261386236376230 17 | 64313739393537363638323362373863653566303266653061396336303736376230363239333639 18 | 3463336365653864630a623232393861653066333031643562623837333063613334636639343464 19 | 33383234393662353630303331636536663165646432373863393331633064613963 20 | 21 | spoiler3: !vault | 22 | $ANSIBLE_VAULT;1.2;AES256;prod 23 | 31613838353831343631353338383665393036643364313433353630636363643030376262653239 24 | 3265343231383736633730656534663531313166363233320a316462396666643965373266663830 25 | 36633066363634303032366532656161326431613831663931356137393838386134323139653963 26 | 3331366462313566640a366365656236643062333362373337366466383138353565663662636136 27 | 34303539373964623237613235663263613932653966383534386335333137656138 28 | 29 | tasks: 30 | - debug: var=spoiler1 31 | - debug: var=spoiler2 32 | - debug: var=spoiler3 33 | 34 | --------------------------------------------------------------------------------