├── .custom-facts.yml.swp ├── add-users.yml ├── adhoc-cmds.sh ├── adhoc.sh ├── ansible.cfg ├── apache-role.yml ├── assert.yml ├── centos-servers.yml ├── check-apache.yml ├── check-mode.yml ├── configure-ssh.yml ├── control-change.yml ├── cool.fact ├── countdown.yml ├── cronjob.yml ├── custom-facts.yml ├── db-secrets.yml ├── debugging.yml ├── disable-selinux.yml ├── empty-role.yml ├── example-timesync-playbook.yml ├── faulty-playbook.yml ├── first-playbook.yml ├── greet.yml ├── group-tasks.yml ├── group_vars ├── dbservers ├── proxy └── webservers ├── handle-errors.yml ├── handler-example.yml ├── host_vars ├── node1.yml ├── node2.yml ├── node3.yml └── node4.yml ├── install-apache.yml ├── isfree.yml ├── keys ├── angela │ └── id_rsa.pub ├── darlene │ └── id_rsa.pub └── tyrell │ └── id_rsa.pub ├── lab10.yml ├── lab11.yml ├── lab12.out ├── lab12.yml ├── lab3.yml ├── lab4.yml ├── lab5.yml ├── lab6.yml ├── lab7.yml ├── lab8.yml ├── lab9.yml ├── local-dns.yml ├── loop-inventory.yml ├── loop-range.yml ├── manage-network.yml ├── manage-software.yml ├── manage-storage.yml ├── manage-users-groups.yml ├── motd.j2 ├── motd.yml ├── multiple-plays.yml ├── myhosts ├── mypass.txt ├── mysecret.txt ├── mysql-role.yml ├── myvars.yml ├── one ├── pause.yml ├── playbooks.log ├── pre-post.yml ├── print-dict.yml ├── print-even.yml ├── print-list.yml ├── range.yml ├── reboot-all.yml ├── reboot-centos.yml ├── register-playbook.yml ├── requirements.yml ├── reuse-playbook.yml ├── roles ├── geerlingguy.haproxy │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ ├── .galaxy_install_info │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ └── haproxy.cfg.j2 │ └── tests │ │ ├── README.md │ │ └── test.yml ├── geerlingguy.mysql │ ├── .ansible-lint │ ├── .github │ │ ├── FUNDING.yml │ │ └── stale.yml │ ├── .gitignore │ ├── .travis.yml │ ├── .yamllint │ ├── LICENSE │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ ├── .galaxy_install_info │ │ └── main.yml │ ├── molecule │ │ └── default │ │ │ ├── converge.yml │ │ │ └── molecule.yml │ ├── tasks │ │ ├── configure.yml │ │ ├── databases.yml │ │ ├── main.yml │ │ ├── replication.yml │ │ ├── secure-installation.yml │ │ ├── setup-Archlinux.yml │ │ ├── setup-Debian.yml │ │ ├── setup-RedHat.yml │ │ ├── users.yml │ │ └── variables.yml │ ├── templates │ │ ├── my.cnf.j2 │ │ ├── root-my.cnf.j2 │ │ └── user-my.cnf.j2 │ └── vars │ │ ├── Archlinux.yml │ │ ├── Debian-10.yml │ │ ├── Debian.yml │ │ ├── RedHat-6.yml │ │ ├── RedHat-7.yml │ │ └── RedHat-8.yml ├── httpd-role │ ├── .travis.yml │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ │ └── index.j2 │ ├── tests │ │ ├── inventory │ │ └── test.yml │ └── vars │ │ └── main.yml ├── jenkins_role │ ├── .github │ │ ├── FUNDING.yml │ │ └── stale.yml │ ├── .gitignore │ ├── .travis.yml │ ├── .yamllint │ ├── LICENSE │ ├── README.md │ ├── defaults │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── meta │ │ ├── .galaxy_install_info │ │ └── main.yml │ ├── molecule │ │ └── default │ │ │ ├── converge.yml │ │ │ ├── java-11.yml │ │ │ ├── java-8.yml │ │ │ ├── molecule.yml │ │ │ ├── playbook-http-port.yml │ │ │ ├── playbook-jenkins-version.yml │ │ │ ├── playbook-plugins-with-home.yml │ │ │ ├── playbook-prefix.yml │ │ │ └── requirements.yml │ ├── tasks │ │ ├── main.yml │ │ ├── plugins.yml │ │ ├── settings.yml │ │ ├── setup-Debian.yml │ │ └── setup-RedHat.yml │ ├── templates │ │ ├── basic-security.groovy.j2 │ │ └── proxy.xml │ ├── tests │ │ └── test-plugins.yml │ └── vars │ │ ├── Debian.yml │ │ └── RedHat.yml ├── myrole │ └── tasks │ │ └── main.yml └── nginx_role │ ├── README.md │ ├── defaults │ └── main.yml │ ├── files │ └── epel.repo │ ├── handlers │ └── main.yml │ ├── meta │ ├── .galaxy_install_info │ └── main.yml │ ├── tasks │ └── main.yml │ ├── templates │ ├── default.conf.j2 │ ├── default.j2 │ ├── nginx.conf.j2 │ └── site.j2 │ └── vars │ └── main.yml ├── secret-vault.txt ├── secret.txt ├── secret2.txt ├── selinux-status.yml ├── server-info.yml ├── show-facts.yml ├── show-secret.txt ├── templates ├── hosts.j2 ├── index.j2 ├── info.j2 ├── range.j2 └── selinux.j2 ├── ubuntu-servers.yml ├── variable-precedence.yml ├── variables-playbook.yml ├── vars1.yml ├── vars2.yml ├── vault-pass.txt ├── vault-playbook.yml └── web-secrets.yml /.custom-facts.yml.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kabary/rhce9/6c4f998b488fb8dbb3a3acac566de10309a07cef/.custom-facts.yml.swp -------------------------------------------------------------------------------- /add-users.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add multiple users 3 | hosts: dbservers 4 | vars: 5 | dbusers: 6 | - username: brad 7 | pass: pass1 8 | - username: david 9 | pass: pass2 10 | - username: jason 11 | pass: pass3 12 | tasks: 13 | - name: Add users 14 | user: 15 | name: "{{ item.username }}" 16 | password: "{{ item.pass | password_hash('sha256') }}" 17 | loop: "{{ dbusers }}" 18 | -------------------------------------------------------------------------------- /adhoc-cmds.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ansible node4 -m raw -a "apt-get install -y python" 4 | ansible all -m command -a "uptime" 5 | ansible node3 -m shell -a 'echo "Hello, Friend!" > /tmp/hello.txt' 6 | -------------------------------------------------------------------------------- /adhoc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ansible localhost -m user -a "name=angela uid=887 password={{ 'L!n*X'| password_hash('sha512') }} generate_ssh_key=yes" 4 | ansible localhost -m user -a "name=tyrell uid=888 password={{ 'L!n*X' | password_hash('sha512') }} generate_ssh_key=yes" 5 | ansible localhost -m user -a "name=darlene uid=889 password={{ 'L!n*X' | password_hash('sha512') }} generate_ssh_key=yes" 6 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | inventory = myhosts 3 | remote_user = elliot 4 | host_key_checking = false 5 | deprecation_warnings= false 6 | roles_path = /usr/share/ansible/roles 7 | log_path = lab12.out 8 | 9 | [privilege_escalation] 10 | become = true 11 | become_method = sudo 12 | become_user = root 13 | become_ack_pass = false 14 | -------------------------------------------------------------------------------- /apache-role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Using httpd-role 3 | hosts: webservers 4 | roles: 5 | - role: httpd-role 6 | sysadmin: angela@linuxhandbook.com 7 | -------------------------------------------------------------------------------- /assert.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: 3 | hosts: node1 4 | tasks: 5 | - name: check free memory 6 | assert: 7 | that: "{{ ansible_facts['memfree_mb'] > 500 }}" 8 | fail_msg: "Low on memory!" 9 | 10 | - name: get file info 11 | stat: 12 | path: /etc/motd 13 | register: motd 14 | 15 | - name: assert /etc/motd is a directory 16 | assert: 17 | that: motd.stat.isdir 18 | fail_msg: "/etc/motd is not a directory!" 19 | -------------------------------------------------------------------------------- /centos-servers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Using when with registers 3 | hosts: all 4 | tasks: 5 | - name: Save the contents of /etc/os-release 6 | command: cat /etc/os-release 7 | register: os_release 8 | 9 | - name: Detect CentOS Servers 10 | debug: 11 | msg: "Running CentOS ..." 12 | when: os_release.stdout.find('CentOS') != -1 13 | -------------------------------------------------------------------------------- /check-apache.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if Apache is Working 3 | hosts: webservers 4 | vars: 5 | webserver_message: "I am running to the finish line." 6 | tasks: 7 | - name: Start httpd 8 | service: 9 | name: httpd 10 | state: started 11 | 12 | - name: Create index.html using Jinja2 13 | template: 14 | src: index.j2 15 | dest: /var/www/html/index.html 16 | -------------------------------------------------------------------------------- /check-mode.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check mode demo 3 | hosts: node1 4 | tasks: 5 | - name: create a file 6 | file: 7 | path: /tmp/file1 8 | state: touch 9 | 10 | - name: create a second file 11 | file: 12 | path: /tmp/file2 13 | state: touch 14 | check_mode: yes 15 | 16 | - name: create a third file 17 | file: 18 | path: /tmp/file3 19 | state: touch 20 | check_mode: no 21 | -------------------------------------------------------------------------------- /configure-ssh.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure SSH 3 | hosts: all 4 | tasks: 5 | - name: Edit SSH Configuration 6 | blockinfile: 7 | path: /etc/ssh/sshd_config 8 | block: | 9 | MaxAuthTries 4 10 | Banner /etc/motd 11 | X11Forwarding no 12 | notify: restart ssh 13 | 14 | handlers: 15 | - name: restart ssh 16 | service: 17 | name: sshd 18 | state: restarted 19 | -------------------------------------------------------------------------------- /control-change.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Control Change 3 | hosts: node1 4 | tasks: 5 | - name: Run the date command 6 | command: date 7 | notify: handler1 8 | changed_when: false 9 | 10 | - name: Run the uptime command 11 | command: uptime 12 | 13 | handlers: 14 | - name: handler1 15 | debug: 16 | msg: "I can handle dates" 17 | -------------------------------------------------------------------------------- /cool.fact: -------------------------------------------------------------------------------- 1 | [fun] 2 | kiwi=fruit 3 | matrix=movie 4 | octupus='8 legs' 5 | -------------------------------------------------------------------------------- /countdown.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Happy Birthday Playbook 3 | hosts: node1 4 | tasks: 5 | - name: Wait for ten seconds 6 | debug: 7 | msg: "{{ 10 - item }} seconds remaining ..." 8 | loop: "{{ range(10) | list }}" 9 | loop_control: 10 | pause: 1 11 | 12 | - name: Display Happy Birthday 13 | debug: 14 | msg: "Happy Birthday!" 15 | -------------------------------------------------------------------------------- /cronjob.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Managing cron jobs 3 | hosts: node2 4 | tasks: 5 | - name: Run this cron job every two mins 6 | cron: 7 | name: "two-mins" 8 | user: elliot 9 | job: logger 'Two minutes have passed!' 10 | minute: '*/2' 11 | 12 | - name: wait for five minutes 13 | pause: 14 | minutes: 5 15 | 16 | - name: Remove the two-mins cron job 17 | cron: 18 | name: "two-mins" 19 | user: elliot 20 | state: absent 21 | -------------------------------------------------------------------------------- /custom-facts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Adding custom facts to node1 3 | hosts: node1 4 | tasks: 5 | - name: Create the facts.d directory 6 | file: 7 | path: /etc/ansible/facts.d 8 | owner: elliot 9 | mode: 775 10 | state: directory 11 | 12 | - name: Copy cool.fact to the facts.d directory 13 | copy: 14 | src: cool.fact 15 | dest: /etc/ansible/facts.d 16 | -------------------------------------------------------------------------------- /db-secrets.yml: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 65386463316530376439623534313832626531336661643862353363393766626565383362373861 3 | 6631636233383336313235383164356630383732386432610a343564373962313735633365353439 4 | 31343736653062613038636265323837306438646664666663353264373331303765323261656665 5 | 3230323033643466660a643531346664386664656366303036653631666434643662336266336434 6 | 61646165353261643165623866666135666366346139613337326461303064616534 7 | -------------------------------------------------------------------------------- /debugging.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: debug demo 3 | hosts: node1 4 | tasks: 5 | - name: show os distro 6 | debug: 7 | msg: "{{ ansible_distribution }}" 8 | 9 | - name: show ip address 10 | debug: 11 | msg: "{{ ansible_facts.default_ipv4.address }}" 12 | verbosity: 2 13 | -------------------------------------------------------------------------------- /disable-selinux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Disable SELinux using RHEL SELinux System Role 3 | hosts: node1 4 | vars: 5 | selinux_state: disabled 6 | tasks: 7 | - name: execute the role and catch errors 8 | block: 9 | - name: apply the role 10 | include_role: 11 | name: rhel-system-roles.selinux 12 | rescue: 13 | #Fail if failed for a different reason that selinux_reboot_required. 14 | - name: handler errors 15 | fail: 16 | msg: "role failed" 17 | when: not selinux_reboot_required 18 | 19 | #Otherwise, reboot the host (as selinux_reboot_required is true) 20 | - name: reboot the host 21 | reboot: 22 | msg: "System is rebooting" 23 | ignore_errors: true 24 | 25 | - name: Apply the role again 26 | include_role: 27 | name: rhel-system-roles.selinux 28 | -------------------------------------------------------------------------------- /empty-role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Using an empty role 3 | hosts: all 4 | tasks: 5 | - name: dbserver role 6 | include_role: 7 | name: myrole 8 | when: inventory_hostname in groups['dbservers'] 9 | -------------------------------------------------------------------------------- /example-timesync-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: node1 3 | vars: 4 | timesync_ntp_servers: 5 | - hostname: 0.north-america.pool.ntp.org 6 | iburst: yes 7 | - hostname: 1.north-america.pool.ntp.org 8 | iburst: yes 9 | - hostname: 2.north-america.pool.ntp.org 10 | iburst: yes 11 | - hostname: 3.north-america.pool.ntp.org 12 | iburst: yes 13 | tzone: America/Chicago 14 | roles: 15 | - rhel-system-roles.timesync 16 | tasks: 17 | - name: Set TimeZone 18 | timezone: 19 | name: "{{ tzone }}" 20 | 21 | -------------------------------------------------------------------------------- /faulty-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Playbook logging enabled 3 | hosts: node1 4 | var: 5 | blog: "Linux Handbook" 6 | tasks: 7 | - name: Print favorite Linux Blog 8 | debug: 9 | msg: "{{ blog }}" 10 | -------------------------------------------------------------------------------- /first-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: first play 3 | hosts: all 4 | tasks: 5 | - name: create a new file 6 | file: 7 | path: /tmp/foo.conf 8 | mode: 0664 9 | owner: elliot 10 | state: touch 11 | 12 | - name: create groups 13 | import_tasks: group-tasks.yml 14 | -------------------------------------------------------------------------------- /greet.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Greet the user 3 | hosts: node1 4 | vars_prompt: 5 | - name: username 6 | prompt: What's your name? 7 | private: no 8 | 9 | tasks: 10 | - name: Greet the user 11 | debug: 12 | msg: Hello {{ username }} 13 | 14 | -------------------------------------------------------------------------------- /group-tasks.yml: -------------------------------------------------------------------------------- 1 | - name: create developers group 2 | group: 3 | name: developers 4 | - name: create security group 5 | group: 6 | name: security 7 | - name: create finance group 8 | group: 9 | name: finance 10 | -------------------------------------------------------------------------------- /group_vars/dbservers: -------------------------------------------------------------------------------- 1 | pkg: mariadb 2 | -------------------------------------------------------------------------------- /group_vars/proxy: -------------------------------------------------------------------------------- 1 | pkg: squid 2 | -------------------------------------------------------------------------------- /group_vars/webservers: -------------------------------------------------------------------------------- 1 | pkg: httpd 2 | -------------------------------------------------------------------------------- /handle-errors.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Handling Errors with Blocks 3 | hosts: node1 4 | tasks: 5 | - name: Handling Errors Example 6 | block: 7 | - name: run a command 8 | command: uptime 9 | 10 | - name: run a bad command 11 | command: blabla 12 | 13 | - name: This task will not run 14 | debug: 15 | msg: "I never run because the task above has failed!" 16 | 17 | rescue: 18 | - name: Runs when the block fails 19 | debug: 20 | msg: "Block failed! let's try to fix it here ..." 21 | 22 | always: 23 | - name: This will always run 24 | debug: 25 | msg: "Whether the block has failed or not ... I will always run!" 26 | -------------------------------------------------------------------------------- /handler-example.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simple Handler Example 3 | hosts: node1 4 | tasks: 5 | - name: Create engineers group 6 | group: 7 | name: engineers 8 | notify: add elliot 9 | 10 | - name: Another task in the play 11 | debug: 12 | msg: "I am just another task." 13 | 14 | handlers: 15 | - name: add elliot 16 | user: 17 | name: elliot 18 | groups: engineers 19 | append: yes 20 | -------------------------------------------------------------------------------- /host_vars/node1.yml: -------------------------------------------------------------------------------- 1 | message: I am a Proxy Server 2 | -------------------------------------------------------------------------------- /host_vars/node2.yml: -------------------------------------------------------------------------------- 1 | message: I am a Web Server 2 | -------------------------------------------------------------------------------- /host_vars/node3.yml: -------------------------------------------------------------------------------- 1 | message: I am a Web Server 2 | -------------------------------------------------------------------------------- /host_vars/node4.yml: -------------------------------------------------------------------------------- 1 | message: I am a Database Server 2 | -------------------------------------------------------------------------------- /install-apache.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install and start Apache Play 3 | hosts: webservers 4 | tasks: 5 | - name: Install and start Apache 6 | block: 7 | - name: Install httpd 8 | yum: 9 | name: httpd 10 | state: latest 11 | 12 | - name: Start and enable httpd 13 | service: 14 | name: httpd 15 | state: started 16 | enabled: yes 17 | 18 | - name: This task is outside the block 19 | debug: 20 | msg: "I am outside the block now ..." 21 | -------------------------------------------------------------------------------- /isfree.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: 3 | hosts: node1 4 | vars: 5 | weekend: true 6 | on_call: "yes" 7 | tasks: 8 | - name: Run if "weekend" is true and "on_call" is false 9 | debug: 10 | msg: "You are free!" 11 | when: weekend and not on_call | bool 12 | -------------------------------------------------------------------------------- /keys/angela/id_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC05Q/X8WGXZ1ZValZcLgRNCrTAAVxyR9zcn+BL7q4NQgekfbMjc+Dj5SpQN/PEPCCqa4dlkrUMbISc/kyxHGu8cvUez0u7+6y251Xz7lvzESEdHFFAnO6PBge4iArz8tYXwtglxmCmQKFiy0gC4Xltaj7Tce3ooSSJCIpMq9KlggQeP59t8dKN/ay4jZndJAykAXOXJuKS5+ep8tsUX28rGoHYWhOHQvaDRBOglHurbr2mRHG4saRpZcM+rnwGqqU0ZZWv4eN18FysA5ObeZHEJWCAwHykgKh8EtdeeatJMSRQWN30yR9K0uXRUN2dX72bAKV6/qcy2CvPcAe8tD2uCtxVoT67771cgV+UGRfCPw0QCCsFlOnigMa5dVKUHRDB6B9xehK1nUcPWaSvvEVhRgCRteK/w3kxJdvaBCaiA0iiIbZ5jG37QFIIOBO6FAdsAdHNE1MMaCvCvF8AHFyb+EXGdqy9m79Sh+wz7VVtoItLhhuXB93N1VMrH92YQT8= ansible-generated on control 2 | -------------------------------------------------------------------------------- /keys/darlene/id_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDAFxfXYyTd9EppSvpgB/FkYpGFGoMlK9+Jj4fORffhF1C0nk2HXVJy+ocozfJRggWCvhSFM44XNTTmegl3BkWVXYT894F9hnl+ixf0LIOMG/2Am1gru43/uudZuMx0aaUiNyLEBirdiXGUy4EeDsnQhvGTBxi84140YPZqp5uOnGgmv2kIlphIUjw51xNrE3Hzb4jQmYFLq3rOoQ/RtRRFDOwUdtA8WNsPEIHJ80hcTn01AcID9wKTUwcz4TmAXc+16PLUCjKoTSfLKw6zvGIS4gVVN7s1jESDQTVRzXZpu++Jzmx4rrYeZ1bB0NJYsRQvjXM0+cfVtgqXSPE0vD/Kl1gGM6kCeKzfHSiRl74ggu5XJ8dRnkmNOR/ChtkqDPAxZZauItx8DwWQ1SR0jZpwg5iGptwpddlRWXULj2OlOqrK7ZcAt5yJgr5CC3P2Mf/CPLE623uRlsz+3Ue8Fva399flrsOyR1F/3MB0REUclrnnaiTwCLby1KRcrRbpayk= ansible-generated on control 2 | -------------------------------------------------------------------------------- /keys/tyrell/id_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDGPOs6u80OwfGlcR2VxGsJ7MdhP57YwjDxBJaKN32qmXIJOqNPK6iGgkIf8G7nqWMcAhaMuhj6KM3FTOegH6FD9P7k3hSEYUC/wNsaK805dN0PdCNR+BlBSHx3OwGqvc7dHDRg2QH7BWBMWdNSroGYL5E9B0HoHlau76lOSPR/vs93b8gwhaDxdgBbc2lxXBBuUgGT0Hxy6tT2lazdxcY5aGAf3NGg6Bzec7z/CkYpen+6z6EMkQJU6kfI6KrHuq7zIoQQxsutEowjVv4oABM0P6f34GM3Y3ItytUId/JulQKwf/3mWMH44Yf9MMG37UCUAUiYtZTbbeQA5HVyCt2UeSyLYvGKhXRc9AJslL1OukcBVEMT79Wde/geJKV0xuzvvAYZk6jUjAPQoRGENTVd9Z0c0pYNCcMJTgFNQlniL2FOGfUy7fmdBsB5TG9OBnoVfIIiZ37EmSa7yjsTGDuwRLJf3Lauc/VZYSDOUs1vcCuSS5V5PEvNQ/zTP6iFxC8= ansible-generated on control 2 | -------------------------------------------------------------------------------- /lab10.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Lab 10 Solution 3 | hosts: node3 4 | vars: 5 | selinux_fcontexts: 6 | - { target: '/web(/.*)?', setype: 'httpd_sys_content_t', ftype: 'd' } 7 | selinux_restore_dirs: 8 | - /web 9 | pre_tasks: 10 | - name: Create /web directory 11 | file: 12 | path: /web 13 | state: directory 14 | roles: 15 | - role: rhel-system-roles.selinux 16 | -------------------------------------------------------------------------------- /lab11.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Lab 11 Solution 3 | hosts: all 4 | tasks: 5 | - name: Create clean-tmp cron job 6 | cron: 7 | name: "clean-tmp" 8 | user: root 9 | job: rm -rf /tmp/* 10 | minute: "0" 11 | hour: "0" 12 | -------------------------------------------------------------------------------- /lab12.out: -------------------------------------------------------------------------------- 1 | 2020-11-28 23:06:41,685 p=1660717 u=elliot n=ansible | ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each: 2 | JSON: Expecting value: line 1 column 1 (char 0) 3 | 4 | Syntax Error while loading YAML. 5 | found unacceptable key (unhashable type: 'AnsibleMapping') 6 | 7 | The error appears to be in '/home/elliot/plays/lab12.yml': line 10, column 14, but may 8 | be elsewhere in the file depending on the exact syntax problem. 9 | 10 | The offending line appears to be: 11 | 12 | name: "{{ item }}" 13 | loop: {{ grps }} 14 | ^ here 15 | We could be wrong, but this one looks like it might be an issue with 16 | missing quotes. Always quote template expression brackets when they 17 | start a value. For instance: 18 | 19 | with_items: 20 | - {{ foo }} 21 | 22 | Should be written as: 23 | 24 | with_items: 25 | - "{{ foo }}" 26 | 27 | 2020-11-28 23:07:14,701 p=1660744 u=elliot n=ansible | ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each: 28 | JSON: Expecting value: line 1 column 1 (char 0) 29 | 30 | Syntax Error while loading YAML. 31 | found unacceptable key (unhashable type: 'AnsibleMapping') 32 | 33 | The error appears to be in '/home/elliot/plays/lab12.yml': line 10, column 14, but may 34 | be elsewhere in the file depending on the exact syntax problem. 35 | 36 | The offending line appears to be: 37 | 38 | name: "{{ item }}" 39 | loop: {{ grps }} 40 | ^ here 41 | We could be wrong, but this one looks like it might be an issue with 42 | missing quotes. Always quote template expression brackets when they 43 | start a value. For instance: 44 | 45 | with_items: 46 | - {{ foo }} 47 | 48 | Should be written as: 49 | 50 | with_items: 51 | - "{{ foo }}" 52 | 53 | 2020-11-28 23:09:19,664 p=1660867 u=elliot n=ansible | [WARNING]: Could not match supplied host pattern, ignoring: lab12.yml 54 | 55 | 2020-11-28 23:09:19,664 p=1660867 u=elliot n=ansible | [WARNING]: No hosts matched, nothing to do 56 | 57 | 2020-11-28 23:09:19,668 p=1660867 u=elliot n=ansible | ERROR! No argument passed to command module (did you mean to run ansible-playbook?) 58 | 2020-11-28 23:09:27,421 p=1660872 u=elliot n=ansible | PLAY [Fix the error] *********************************************************** 59 | 2020-11-28 23:09:27,432 p=1660872 u=elliot n=ansible | TASK [Gathering Facts] ********************************************************* 60 | 2020-11-28 23:09:28,545 p=1660872 u=elliot n=ansible | ok: [localhost] 61 | 2020-11-28 23:09:28,562 p=1660872 u=elliot n=ansible | TASK [create groups] *********************************************************** 62 | 2020-11-28 23:09:29,020 p=1660872 u=elliot n=ansible | changed: [localhost] => (item=devops) 63 | 2020-11-28 23:09:29,264 p=1660872 u=elliot n=ansible | changed: [localhost] => (item=secops) 64 | 2020-11-28 23:09:29,506 p=1660872 u=elliot n=ansible | changed: [localhost] => (item=netops) 65 | 2020-11-28 23:09:29,510 p=1660872 u=elliot n=ansible | PLAY RECAP ********************************************************************* 66 | 2020-11-28 23:09:29,510 p=1660872 u=elliot n=ansible | localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 67 | 2020-11-28 23:10:28,904 p=1661067 u=elliot n=ansible | PLAY [Fix the error] *********************************************************** 68 | 2020-11-28 23:10:28,914 p=1661067 u=elliot n=ansible | TASK [Gathering Facts] ********************************************************* 69 | 2020-11-28 23:10:30,045 p=1661067 u=elliot n=ansible | ok: [localhost] 70 | 2020-11-28 23:10:30,062 p=1661067 u=elliot n=ansible | TASK [create groups] *********************************************************** 71 | 2020-11-28 23:10:31,001 p=1661067 u=elliot n=ansible | changed: [localhost] => (item=devops) 72 | 2020-11-28 23:10:31,631 p=1661067 u=elliot n=ansible | changed: [localhost] => (item=secops) 73 | 2020-11-28 23:10:32,278 p=1661067 u=elliot n=ansible | changed: [localhost] => (item=netops) 74 | 2020-11-28 23:10:32,282 p=1661067 u=elliot n=ansible | PLAY RECAP ********************************************************************* 75 | 2020-11-28 23:10:32,282 p=1661067 u=elliot n=ansible | localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 76 | -------------------------------------------------------------------------------- /lab12.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Fix the error 3 | hosts: localhost 4 | vars: 5 | grps: ["devops","secops","netops"] 6 | tasks: 7 | - name: create groups 8 | group: 9 | name: "{{ item }}" 10 | loop: "{{ grps }}" 11 | -------------------------------------------------------------------------------- /lab3.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Lab 3 Solution 3 | hosts: all 4 | tasks: 5 | - name: install nmap 6 | package: 7 | name: nmap 8 | state: present 9 | 10 | - name: create an XZ archive 11 | archive: 12 | path: /home 13 | dest: /tmp/home.tar.bz2 14 | format: bz2 15 | -------------------------------------------------------------------------------- /lab4.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Lab 4 Solution 3 | hosts: all 4 | tasks: 5 | - name: Run free command and capture output 6 | command: free -h 7 | register: freemem 8 | 9 | - name: Display free memory 10 | debug: 11 | msg: "{{ freemem.stdout }}" 12 | 13 | - name: Display IPv4 address 14 | debug: 15 | msg: "{{ ansible_facts.default_ipv4.address }}" 16 | -------------------------------------------------------------------------------- /lab5.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Lab 5 Solution 3 | hosts: localhost 4 | tasks: 5 | - name: Display even numbers 20<= num <=40 6 | debug: 7 | msg: "{{ item }}" 8 | loop: "{{ range(20,41,2) | list }}" 9 | -------------------------------------------------------------------------------- /lab6.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Lab 6 Solution 3 | hosts: all 4 | tasks: 5 | - name: Install nfs-utils on CentOS servers 6 | yum: 7 | name: nfs-utils 8 | when: ansible_facts['distribution'] == "CentOS" 9 | -------------------------------------------------------------------------------- /lab7.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Lab 7 Solution 3 | hosts: all 4 | tasks: 5 | - name: Edit /etc/motd using Jinja2 6 | template: 7 | src: motd.j2 8 | dest: /etc/motd 9 | -------------------------------------------------------------------------------- /lab8.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Lab 9 Solution 3 | hosts: proxy 4 | 5 | -------------------------------------------------------------------------------- /lab9.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Lab 9 Solution 3 | hosts: proxy 4 | vars: 5 | haproxy_backend_servers: 6 | - name: webserver1 7 | address: node2 8 | - name: webserver2 9 | address: node3 10 | roles: 11 | - role: geerlingguy.haproxy 12 | 13 | 14 | -------------------------------------------------------------------------------- /local-dns.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Dynamically Update /etc/hosts File 3 | hosts: all 4 | tasks: 5 | - name: Update /etc/hosts using Jinja2 6 | template: 7 | src: hosts.j2 8 | dest: /etc/hosts 9 | -------------------------------------------------------------------------------- /loop-inventory.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Loop over Inventory 3 | hosts: node1 4 | tasks: 5 | - name: Ping all hosts 6 | command: ping -c 1 "{{ item }}" 7 | loop: "{{ groups['all'] }}" 8 | -------------------------------------------------------------------------------- /loop-range.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Range Loop 3 | hosts: node1 4 | tasks: 5 | - name: Range Loop 6 | debug: 7 | msg: 192.168.1.{{ item }} 8 | loop: "{{ range(0,255,2) | list }}" 9 | -------------------------------------------------------------------------------- /manage-network.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Configure a NIC 3 | hosts: node1 4 | tasks: 5 | - name: Configure eth1 6 | nmcli: 7 | ifname: eth1 8 | conn_name: ether-two 9 | type: ethernet 10 | ip4: 192.168.177.3/16 11 | dns4: 12 | - 8.8.8.8 13 | - 8.8.4.4 14 | state: present 15 | 16 | - name: Set hostname 17 | hostname: 18 | name: node1.linuxhandbook.local 19 | 20 | - name: Enable http and https in firewall public zone 21 | firewalld: 22 | zone: public 23 | service: "{{ item }}" 24 | permanent: yes 25 | state: enabled 26 | loop: [http, https] 27 | notify: restart firewalld 28 | 29 | handlers: 30 | - name: restart firewalld 31 | service: 32 | name: firewalld 33 | state: restarted 34 | -------------------------------------------------------------------------------- /manage-software.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Manage Software 3 | hosts: node1 4 | vars: 5 | pkg_name: zabbix-agent 6 | tasks: 7 | - name: Create a new repo 8 | yum_repository: 9 | file: zabbix 10 | name: zabbix-monitoring 11 | baseurl: https://repo.zabbix.com/zabbix/5.2/rhel/8/x86_64/ 12 | description: "Zabbix 5.2 Repo" 13 | enabled: yes 14 | gpgcheck: no 15 | 16 | - name: Install zabbix agent 17 | yum: 18 | name: "{{ pkg_name }}" 19 | state: present 20 | 21 | - name: Get package facts 22 | package_facts: 23 | manager: auto 24 | 25 | - name: Display zabbix-agent package facts 26 | debug: 27 | var: ansible_facts.packages[pkg_name] 28 | when: pkg_name in ansible_facts.packages 29 | -------------------------------------------------------------------------------- /manage-storage.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Manage Storage 3 | hosts: node4 4 | vars: 5 | partitions: 6 | - number: 1 7 | start: 0% 8 | end: 2GiB 9 | - number: 2 10 | start: 2GiB 11 | end: 4GiB 12 | vgs: 13 | - name: dbvg 14 | devices: ['/dev/sdc1','/dev/sdc2'] 15 | lvs: 16 | - name: dblv 17 | size: 3G 18 | vgrp: dbvg 19 | mnt: /database 20 | tasks: 21 | # Replace /dev/sdc with your secondary disk name 22 | - name: Create two new partitions on /dev/sdc 23 | parted: 24 | device: /dev/sdc 25 | number: "{{ item.number }}" 26 | part_start: "{{ item.start }}" 27 | part_end: "{{ item.end }}" 28 | state: present 29 | loop: "{{ partitions }}" 30 | 31 | - name: Create volume group 32 | lvg: 33 | vg: "{{ item.name }}" 34 | pvs: "{{ item.devices }}" 35 | loop: "{{ vgs }}" 36 | 37 | - name: Create logical volume 38 | lvol: 39 | vg: "{{ item.vgrp }}" 40 | lv: "{{ item.name }}" 41 | size: "{{ item.size }}" 42 | loop: "{{ lvs }}" 43 | 44 | - name: Create filesystem on logical volume 45 | filesystem: 46 | dev: "/dev/{{ item.vgrp }}/{{ item.name }}" 47 | fstype: ext4 48 | loop: "{{ lvs }}" 49 | 50 | - name: Create /database directory 51 | file: 52 | path: /database 53 | mode: 0755 54 | state: directory 55 | 56 | - name: Mount logical volume 57 | mount: 58 | src: "/dev/{{ item.vgrp }}/{{ item.name }}" 59 | path: "{{ item.mnt }}" 60 | fstype: ext4 61 | state: mounted 62 | loop: "{{ lvs }}" 63 | -------------------------------------------------------------------------------- /manage-users-groups.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Manage Users & Groups 3 | hosts: node4 4 | vars: 5 | grps: 6 | - devops 7 | - secops 8 | usrs: 9 | - username: angela 10 | id: 887 11 | pass: 'L!n*X' 12 | - username: tyrell 13 | id: 888 14 | pass: 'L!n*X' 15 | - username: darlene 16 | id: 889 17 | pass: 'L!n*X' 18 | tasks: 19 | - name: Create groups 20 | group: 21 | name: "{{ item }}" 22 | loop: "{{ grps }}" 23 | 24 | - name: Create users (and add users to group secops) 25 | user: 26 | name: "{{ item.username }}" 27 | uid: "{{ item.id }}" 28 | password: "{{ item.pass | password_hash('sha512') }}" 29 | groups: "{{ grps[1] }}" 30 | loop: "{{ usrs }}" 31 | 32 | - name: Give secops sudo access 33 | copy: 34 | content: "%secops ALL=(ALL) NOPASSWD: ALL" 35 | dest: /etc/sudoers.d/secops 36 | mode: 0400 37 | 38 | - name: Copy users SSH public key 39 | authorized_key: 40 | user: "{{ item.username }}" 41 | key: "{{ lookup('file', './keys/' + item.username + '/id_rsa.pub') }}" 42 | loop: "{{ usrs }}" 43 | -------------------------------------------------------------------------------- /motd.j2: -------------------------------------------------------------------------------- 1 | Welcome to {{ inventory_hostname }}. 2 | My IP address is {{ ansible_facts['default_ipv4']['address'] }}. 3 | -------------------------------------------------------------------------------- /motd.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set motd on all nodes 3 | gather_facts: false 4 | hosts: all 5 | tasks: 6 | - name: Set motd = value of message variable. 7 | copy: 8 | content: "{{ message }}" 9 | dest: /etc/motd 10 | -------------------------------------------------------------------------------- /multiple-plays.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: first play 3 | hosts: all 4 | gather_facts: no 5 | tasks: 6 | - name: install tmux 7 | package: 8 | name: tmux 9 | state: present 10 | 11 | - name: create an archive 12 | archive: 13 | path: /var/log 14 | dest: /tmp/logs.tar.gz 15 | format: gz 16 | 17 | - name: second play 18 | hosts: node4 19 | gather_facts: no 20 | tasks: 21 | - name: install git 22 | apt: 23 | name: git 24 | state: present 25 | tags: git 26 | -------------------------------------------------------------------------------- /myhosts: -------------------------------------------------------------------------------- 1 | [proxy] 2 | node1 3 | 4 | [webservers] 5 | node2 6 | node3 7 | 8 | [dbservers] 9 | node4 10 | -------------------------------------------------------------------------------- /mypass.txt: -------------------------------------------------------------------------------- 1 | 7uZAcMBVz 2 | -------------------------------------------------------------------------------- /mysecret.txt: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 35633461366339623232333335373037316565633135623332343530613661633331383237363333 3 | 3961313730353936336239366162353566326266663461390a373764653332376631366533333632 4 | 30363437613333653061626565363434393061306265333766393366393639336262376666393133 5 | 3537333030326530650a616263383736383636393435313561633466346563383664626466356364 6 | 32636161306432306565363364653035626337663261323439383835646336396366 7 | -------------------------------------------------------------------------------- /mysql-role.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Applying geerlingguy.mysql role 3 | hosts: dbservers 4 | roles: 5 | - geerlingguy.mysql 6 | -------------------------------------------------------------------------------- /myvars.yml: -------------------------------------------------------------------------------- 1 | --- 2 | port_nums: [21,22,23,25,80,443] 3 | 4 | users { 5 | bob: 6 | username: bob 7 | uid: 1122 8 | shell: /bin/bash 9 | lisa: 10 | username: lisa 11 | uid: 2233 12 | shelil: /bin/sh 13 | } 14 | -------------------------------------------------------------------------------- /one: -------------------------------------------------------------------------------- 1 | 123 2 | -------------------------------------------------------------------------------- /pause.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: pause in loops 3 | hosts: node1 4 | vars: 5 | list1: [2,3,5,7,9,11,13,17,19] 6 | tasks: 7 | - name: Range of numbers 8 | debug: 9 | msg: "{{ item }}" 10 | loop: "{{ range(1,10,2) | list }}" 11 | - name: Print out the list1 12 | debug: 13 | msg: "{{ item }}" 14 | loop: "{{ list1 }}" 15 | loop_control: 16 | pause: 2 17 | -------------------------------------------------------------------------------- /pre-post.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Understanding Order of Task Execution 3 | hosts: node1 4 | tasks: 5 | - name: A regular task 6 | debug: 7 | msg: "I am just a regular task." 8 | 9 | post_tasks: 10 | - name: Runs last 11 | debug: 12 | msg: "I will run last (post_task)." 13 | 14 | pre_tasks: 15 | - name: Runs first 16 | debug: 17 | msg: "I will run first (pre_task)." 18 | 19 | roles: 20 | - role: myrole 21 | -------------------------------------------------------------------------------- /print-dict.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Print Dictionary 3 | hosts: node1 4 | vars: 5 | employee: 6 | name: "Elliot Alderson" 7 | title: "Penetration Tester" 8 | company: "Linux HandBook" 9 | tasks: 10 | - name: Print employee dictionary 11 | debug: 12 | msg: "{{ item }}" 13 | loop: "{{ employee | dict2items }}" 14 | -------------------------------------------------------------------------------- /print-even.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Print Some Numbers 3 | hosts: node1 4 | tasks: 5 | - name: Print Even Numbers 6 | debug: 7 | msg: Number {{ item }} is Even. 8 | loop: "{{ range(1,11) | list }}" 9 | when: item % 2 == 0 10 | -------------------------------------------------------------------------------- /print-list.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: print list 3 | hosts: node1 4 | vars: 5 | prime: [2,3,5,7,11] 6 | tasks: 7 | - name: Show first five prime numbers 8 | debug: 9 | msg: "{{ item }}" 10 | loop: "{{ prime }}" 11 | -------------------------------------------------------------------------------- /range.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: range playbook 3 | hosts: node1 4 | tasks: 5 | - name: 6 | template: 7 | src: range.j2 8 | dest: /tmp/range.out 9 | -------------------------------------------------------------------------------- /reboot-all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Reboot Servers 3 | hosts: all 4 | tasks: 5 | - name: Reboot CentOS 8 servers 6 | reboot: 7 | msg: "Server is rebooting ..." 8 | when: ansible_facts['distribution'] == "CentOS" or ansible_facts['distribution'] == "Ubuntu" 9 | -------------------------------------------------------------------------------- /reboot-centos.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Reboot Servers 3 | hosts: all 4 | tasks: 5 | - name: Reboot CentOS 8 servers 6 | reboot: 7 | msg: "Server is rebooting ..." 8 | when: ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "8" 9 | -------------------------------------------------------------------------------- /register-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Register Playbook Showcase 3 | hosts: proxy 4 | tasks: 5 | - name: Run a command 6 | command: uptime 7 | register: server_uptime 8 | 9 | - name: Inspect the server_uptime variable 10 | debug: 11 | var: server_uptime 12 | 13 | - name: Show the server uptime 14 | debug: 15 | msg: "{{ server_uptime.stdout }}" 16 | -------------------------------------------------------------------------------- /requirements.yml: -------------------------------------------------------------------------------- 1 | # From Ansible Galaxy 2 | - src: geerlingguy.haproxy 3 | 4 | # From Github 5 | - src: https://github.com/bennojoy/nginx 6 | name: nginx_role 7 | version: master 8 | 9 | # From Ansible Galaxy 10 | - src: geerlingguy.jenkins 11 | name: jenkins_role 12 | -------------------------------------------------------------------------------- /reuse-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Reusing playbooks 3 | hosts: all 4 | tasks: 5 | - name: Reboot the servers 6 | reboot: 7 | msg: Server is rebooting ... 8 | 9 | - name: Run first playbook 10 | include: first-playbook.yml 11 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | tests/test.sh 3 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | services: docker 3 | 4 | env: 5 | - distro: centos7 6 | - distro: centos6 7 | - distro: ubuntu1604 8 | - distro: ubuntu1404 9 | - distro: ubuntu1204 10 | 11 | script: 12 | # Configure test script so we can run extra tests after playbook is run. 13 | - export container_id=$(date +%s) 14 | - export cleanup=false 15 | 16 | # Download test shim. 17 | - wget -O ${PWD}/tests/test.sh https://gist.githubusercontent.com/geerlingguy/73ef1e5ee45d8694570f334be385e181/raw/ 18 | - chmod +x ${PWD}/tests/test.sh 19 | 20 | # Run tests. 21 | - ${PWD}/tests/test.sh 22 | 23 | # Make sure haproxy is installed. 24 | - 'docker exec --tty ${container_id} env TERM=xterm haproxy -v' 25 | 26 | notifications: 27 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 28 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Jeff Geerling 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/README.md: -------------------------------------------------------------------------------- 1 | # Ansible Role: HAProxy 2 | 3 | [![Build Status](https://travis-ci.org/geerlingguy/ansible-role-haproxy.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-haproxy) 4 | 5 | Installs HAProxy on RedHat/CentOS and Debian/Ubuntu Linux servers. 6 | 7 | **Note**: This role _officially_ supports HAProxy versions 1.4 or 1.5. Future versions may require some rework. 8 | 9 | ## Requirements 10 | 11 | None. 12 | 13 | ## Role Variables 14 | 15 | Available variables are listed below, along with default values (see `defaults/main.yml`): 16 | 17 | haproxy_socket: /var/lib/haproxy/stats 18 | 19 | The socket through which HAProxy can communicate (for admin purposes or statistics). To disable/remove this directive, set `haproxy_socket: ''` (an empty string). 20 | 21 | haproxy_chroot: /var/lib/haproxy 22 | 23 | The jail directory where chroot() will be performed before dropping privileges. To disable/remove this directive, set `haproxy_chroot: ''` (an empty string). Only change this if you know what you're doing! 24 | 25 | haproxy_user: haproxy 26 | haproxy_group: haproxy 27 | 28 | The user and group under which HAProxy should run. Only change this if you know what you're doing! 29 | 30 | haproxy_frontend_name: 'hafrontend' 31 | haproxy_frontend_bind_address: '*' 32 | haproxy_frontend_port: 80 33 | haproxy_frontend_mode: 'http' 34 | 35 | HAProxy frontend configuration directives. 36 | 37 | haproxy_backend_name: 'habackend' 38 | haproxy_backend_mode: 'http' 39 | haproxy_backend_balance_method: 'roundrobin' 40 | haproxy_backend_httpchk: 'HEAD / HTTP/1.1\r\nHost:localhost' 41 | 42 | HAProxy backend configuration directives. 43 | 44 | haproxy_backend_servers: 45 | - name: app1 46 | address: 192.168.0.1:80 47 | - name: app2 48 | address: 192.168.0.2:80 49 | 50 | A list of backend servers (name and address) to which HAProxy will distribute requests. 51 | 52 | haproxy_global_vars: 53 | - 'ssl-default-bind-ciphers ABCD+KLMJ:...' 54 | - 'ssl-default-bind-options no-sslv3' 55 | 56 | A list of extra global variables to add to the global configuration section inside `haproxy.cfg`. 57 | 58 | ## Dependencies 59 | 60 | None. 61 | 62 | ## Example Playbook 63 | 64 | - hosts: balancer 65 | sudo: yes 66 | roles: 67 | - { role: geerlingguy.haproxy } 68 | 69 | ## License 70 | 71 | MIT / BSD 72 | 73 | ## Author Information 74 | 75 | This role was created in 2015 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). 76 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | haproxy_socket: /var/lib/haproxy/stats 3 | haproxy_chroot: /var/lib/haproxy 4 | haproxy_user: haproxy 5 | haproxy_group: haproxy 6 | 7 | # Frontend settings. 8 | haproxy_frontend_name: 'hafrontend' 9 | haproxy_frontend_bind_address: '*' 10 | haproxy_frontend_port: 80 11 | haproxy_frontend_mode: 'http' 12 | 13 | # Backend settings. 14 | haproxy_backend_name: 'habackend' 15 | haproxy_backend_mode: 'http' 16 | haproxy_backend_balance_method: 'roundrobin' 17 | haproxy_backend_httpchk: 'HEAD / HTTP/1.1\r\nHost:localhost' 18 | 19 | # List of backend servers. 20 | haproxy_backend_servers: [] 21 | # - name: app1 22 | # address: 192.168.0.1:80 23 | # - name: app2 24 | # address: 192.168.0.2:80 25 | 26 | # Extra global vars (see README for example usage). 27 | haproxy_global_vars: [] 28 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart haproxy 3 | service: name=haproxy state=restarted 4 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/meta/.galaxy_install_info: -------------------------------------------------------------------------------- 1 | {install_date: 'Thu Nov 26 03:27:59 2020', version: 1.1.2} 2 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: [] 3 | 4 | galaxy_info: 5 | author: geerlingguy 6 | description: HAProxy installation and configuration. 7 | company: "Midwestern Mac, LLC" 8 | license: "license (BSD, MIT)" 9 | min_ansible_version: 2.2 10 | platforms: 11 | - name: EL 12 | versions: 13 | - 6 14 | - 7 15 | - name: Ubuntu 16 | versions: 17 | - precise 18 | - trusty 19 | - xenial 20 | galaxy_tags: 21 | - web 22 | - networking 23 | - cloud 24 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure HAProxy is installed. 3 | package: name=haproxy state=present 4 | 5 | - name: Ensure HAProxy is enabled (so init script will start it on Debian). 6 | lineinfile: 7 | dest: /etc/default/haproxy 8 | regexp: "^ENABLED.+$" 9 | line: "ENABLED=1" 10 | state: present 11 | when: ansible_os_family == 'Debian' 12 | 13 | - name: Get HAProxy version. 14 | command: haproxy -v 15 | register: haproxy_version_result 16 | changed_when: false 17 | check_mode: no 18 | 19 | - name: Set HAProxy version. 20 | set_fact: 21 | haproxy_version: "{{ '1.5' if '1.5.' in haproxy_version_result.stdout else '1.4' }}" 22 | 23 | - name: Copy HAProxy configuration in place. 24 | template: 25 | src: haproxy.cfg.j2 26 | dest: /etc/haproxy/haproxy.cfg 27 | mode: 0644 28 | validate: haproxy -f %s -c -q 29 | notify: restart haproxy 30 | 31 | - name: Ensure HAProxy is started and enabled on boot. 32 | service: name=haproxy state=started enabled=yes 33 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/templates/haproxy.cfg.j2: -------------------------------------------------------------------------------- 1 | global 2 | log /dev/log local0 3 | log /dev/log local1 notice 4 | {% if haproxy_socket != '' %} 5 | stats socket {{ haproxy_socket }} level admin 6 | {% endif %} 7 | {% if haproxy_chroot != '' %} 8 | chroot {{ haproxy_chroot }} 9 | {% endif %} 10 | user {{ haproxy_user }} 11 | group {{ haproxy_group }} 12 | daemon 13 | {% for global_var in haproxy_global_vars %} 14 | {{ global_var }} 15 | {% endfor %} 16 | 17 | defaults 18 | log global 19 | mode http 20 | option httplog 21 | option dontlognull 22 | {% if haproxy_version == '1.4' %} 23 | contimeout 5000 24 | clitimeout 50000 25 | srvtimeout 50000 26 | {% else %} 27 | timeout connect 5000 28 | timeout client 50000 29 | timeout server 50000 30 | {% endif %} 31 | {% if ansible_os_family == 'Debian' %} 32 | errorfile 400 /etc/haproxy/errors/400.http 33 | errorfile 403 /etc/haproxy/errors/403.http 34 | errorfile 408 /etc/haproxy/errors/408.http 35 | errorfile 500 /etc/haproxy/errors/500.http 36 | errorfile 502 /etc/haproxy/errors/502.http 37 | errorfile 503 /etc/haproxy/errors/503.http 38 | errorfile 504 /etc/haproxy/errors/504.http 39 | {% endif %} 40 | 41 | frontend {{ haproxy_frontend_name }} 42 | bind {{ haproxy_frontend_bind_address }}:{{ haproxy_frontend_port }} 43 | mode {{ haproxy_frontend_mode }} 44 | default_backend {{ haproxy_backend_name }} 45 | 46 | backend {{ haproxy_backend_name }} 47 | mode {{ haproxy_backend_mode }} 48 | balance {{ haproxy_backend_balance_method }} 49 | option forwardfor 50 | {% if haproxy_backend_httpchk != '' %} 51 | option httpchk {{ haproxy_backend_httpchk }} 52 | {% endif %} 53 | cookie SERVERID insert indirect 54 | {% for backend in haproxy_backend_servers %} 55 | server {{ backend.name }} {{ backend.address }} cookie {{ backend.name }} check 56 | {% endfor %} 57 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/tests/README.md: -------------------------------------------------------------------------------- 1 | # Ansible Role tests 2 | 3 | To run the test playbook(s) in this directory: 4 | 5 | 1. Install and start Docker. 6 | 1. Download the test shim (see .travis.yml file for the URL) into `tests/test.sh`: 7 | - `wget -O tests/test.sh https://gist.githubusercontent.com/geerlingguy/73ef1e5ee45d8694570f334be385e181/raw/` 8 | 1. Make the test shim executable: `chmod +x tests/test.sh`. 9 | 1. Run (from the role root directory) `distro=[distro] playbook=[playbook] ./tests/test.sh` 10 | 11 | If you don't want the container to be automatically deleted after the test playbook is run, add the following environment variables: `cleanup=false container_id=$(date +%s)` 12 | -------------------------------------------------------------------------------- /roles/geerlingguy.haproxy/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | 4 | vars: 5 | haproxy_socket: '' 6 | haproxy_chroot: '' 7 | haproxy_user: root 8 | haproxy_group: root 9 | 10 | haproxy_backend_servers: 11 | - name: app1 12 | address: 127.0.0.1:8080 13 | 14 | pre_tasks: 15 | - name: Update apt cache. 16 | apt: update_cache=yes cache_valid_time=600 17 | when: ansible_os_family == 'Debian' 18 | 19 | roles: 20 | - role_under_test 21 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/.ansible-lint: -------------------------------------------------------------------------------- 1 | skip_list: 2 | - '204' 3 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | --- 3 | github: geerlingguy 4 | patreon: geerlingguy 5 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: 30 9 | 10 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) 11 | onlyLabels: [] 12 | 13 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 14 | exemptLabels: 15 | - pinned 16 | - security 17 | - planned 18 | 19 | # Set to true to ignore issues in a project (defaults to false) 20 | exemptProjects: false 21 | 22 | # Set to true to ignore issues in a milestone (defaults to false) 23 | exemptMilestones: false 24 | 25 | # Set to true to ignore issues with an assignee (defaults to false) 26 | exemptAssignees: false 27 | 28 | # Label to use when marking as stale 29 | staleLabel: stale 30 | 31 | # Limit the number of actions per hour, from 1-30. Default is 30 32 | limitPerRun: 30 33 | 34 | pulls: 35 | markComment: |- 36 | This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! 37 | 38 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. 39 | 40 | unmarkComment: >- 41 | This pull request is no longer marked for closure. 42 | 43 | closeComment: >- 44 | This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. 45 | 46 | issues: 47 | markComment: |- 48 | This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 49 | 50 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 51 | 52 | unmarkComment: >- 53 | This issue is no longer marked for closure. 54 | 55 | closeComment: >- 56 | This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 57 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | */__pycache__ 3 | *.pyc 4 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | services: docker 4 | 5 | env: 6 | global: 7 | - ROLE_NAME: mysql 8 | matrix: 9 | - MOLECULE_DISTRO: centos8 10 | - MOLECULE_DISTRO: centos7 11 | - MOLECULE_DISTRO: centos6 12 | - MOLECULE_DISTRO: ubuntu1804 13 | - MOLECULE_DISTRO: ubuntu1604 14 | - MOLECULE_DISTRO: debian10 15 | 16 | install: 17 | # Install test dependencies. 18 | - pip install molecule yamllint ansible-lint docker 19 | 20 | before_script: 21 | # Use actual Ansible Galaxy role name for the project directory. 22 | - cd ../ 23 | - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME 24 | - cd geerlingguy.$ROLE_NAME 25 | 26 | script: 27 | # Run tests. 28 | - molecule test 29 | 30 | notifications: 31 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 32 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | rules: 4 | line-length: 5 | max: 160 6 | level: warning 7 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Jeff Geerling 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/README.md: -------------------------------------------------------------------------------- 1 | # Ansible Role: MySQL 2 | 3 | [![Build Status](https://travis-ci.org/geerlingguy/ansible-role-mysql.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-mysql) 4 | 5 | Installs and configures MySQL or MariaDB server on RHEL/CentOS or Debian/Ubuntu servers. 6 | 7 | ## Requirements 8 | 9 | No special requirements; note that this role requires root access, so either run it in a playbook with a global `become: yes`, or invoke the role in your playbook like: 10 | 11 | - hosts: database 12 | roles: 13 | - role: geerlingguy.mysql 14 | become: yes 15 | 16 | ## Role Variables 17 | 18 | Available variables are listed below, along with default values (see `defaults/main.yml`): 19 | 20 | mysql_user_home: /root 21 | mysql_user_name: root 22 | mysql_user_password: root 23 | 24 | The home directory inside which Python MySQL settings will be stored, which Ansible will use when connecting to MySQL. This should be the home directory of the user which runs this Ansible role. The `mysql_user_name` and `mysql_user_password` can be set if you are running this role under a non-root user account and want to set a non-root user. 25 | 26 | mysql_root_home: /root 27 | mysql_root_username: root 28 | mysql_root_password: root 29 | 30 | The MySQL root user account details. 31 | 32 | mysql_root_password_update: false 33 | 34 | Whether to force update the MySQL root user's password. By default, this role will only change the root user's password when MySQL is first configured. You can force an update by setting this to `yes`. 35 | 36 | > Note: If you get an error like `ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)` after a failed or interrupted playbook run, this usually means the root password wasn't originally updated to begin with. Try either removing the `.my.cnf` file inside the configured `mysql_user_home` or updating it and setting `password=''` (the insecure default password). Run the playbook again, with `mysql_root_password_update` set to `yes`, and the setup should complete. 37 | 38 | > Note: If you get an error like `ERROR 1698 (28000): Access denied for user 'root'@'localhost' (using password: YES)` when trying to log in from the CLI you might need to run as root or sudoer. 39 | 40 | mysql_enabled_on_startup: true 41 | 42 | Whether MySQL should be enabled on startup. 43 | 44 | mysql_config_file: *default value depends on OS* 45 | mysql_config_include_dir: *default value depends on OS* 46 | 47 | The main my.cnf configuration file and include directory. 48 | 49 | overwrite_global_mycnf: true 50 | 51 | Whether the global my.cnf should be overwritten each time this role is run. Setting this to `no` tells Ansible to only create the `my.cnf` file if it doesn't exist. This should be left at its default value (`yes`) if you'd like to use this role's variables to configure MySQL. 52 | 53 | mysql_config_include_files: [] 54 | 55 | A list of files that should override the default global my.cnf. Each item in the array requires a "src" parameter which is a path to a file. An optional "force" parameter can force the file to be updated each time ansible runs. 56 | 57 | mysql_databases: [] 58 | 59 | The MySQL databases to create. A database has the values `name`, `encoding` (defaults to `utf8`), `collation` (defaults to `utf8_general_ci`) and `replicate` (defaults to `1`, only used if replication is configured). The formats of these are the same as in the `mysql_db` module. 60 | 61 | You can also delete a database (or ensure it's not on the server) by setting `state` to `absent` (defaults to `present`). 62 | 63 | mysql_users: [] 64 | 65 | The MySQL users and their privileges. A user has the values: 66 | 67 | - `name` 68 | - `host` (defaults to `localhost`) 69 | - `password` (can be plaintext or encrypted—if encrypted, set `encrypted: yes`) 70 | - `encrypted` (defaults to `no`) 71 | - `priv` (defaults to `*.*:USAGE`) 72 | - `append_privs` (defaults to `no`) 73 | - `state` (defaults to `present`) 74 | 75 | The formats of these are the same as in the `mysql_user` module. 76 | 77 | mysql_packages: 78 | - mysql 79 | - mysql-server 80 | 81 | (OS-specific, RedHat/CentOS defaults listed here) Packages to be installed. In some situations, you may need to add additional packages, like `mysql-devel`. 82 | 83 | mysql_enablerepo: "" 84 | 85 | (RedHat/CentOS only) If you have enabled any additional repositories (might I suggest geerlingguy.repo-epel or geerlingguy.repo-remi), those repositories can be listed under this variable (e.g. `remi,epel`). This can be handy, as an example, if you want to install later versions of MySQL. 86 | 87 | mysql_python_package_debian: python3-mysqldb 88 | 89 | (Ubuntu/Debian only) If you need to explicitly override the MySQL Python package, you can set it here. Set this to `python-mysqldb` if using older distributions running Python 2. 90 | 91 | mysql_port: "3306" 92 | mysql_bind_address: '0.0.0.0' 93 | mysql_datadir: /var/lib/mysql 94 | mysql_socket: *default value depends on OS* 95 | mysql_pid_file: *default value depends on OS* 96 | 97 | Default MySQL connection configuration. 98 | 99 | mysql_log_file_group: mysql *adm on Debian* 100 | mysql_log: "" 101 | mysql_log_error: *default value depends on OS* 102 | mysql_syslog_tag: *default value depends on OS* 103 | 104 | MySQL logging configuration. Setting `mysql_log` (the general query log) or `mysql_log_error` to `syslog` will make MySQL log to syslog using the `mysql_syslog_tag`. 105 | 106 | mysql_slow_query_log_enabled: false 107 | mysql_slow_query_log_file: *default value depends on OS* 108 | mysql_slow_query_time: 2 109 | 110 | Slow query log settings. Note that the log file will be created by this role, but if you're running on a server with SELinux or AppArmor, you may need to add this path to the allowed paths for MySQL, or disable the mysql profile. For example, on Debian/Ubuntu, you can run `sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/usr.sbin.mysqld && sudo service apparmor restart`. 111 | 112 | mysql_key_buffer_size: "256M" 113 | mysql_max_allowed_packet: "64M" 114 | mysql_table_open_cache: "256" 115 | [...] 116 | 117 | The rest of the settings in `defaults/main.yml` control MySQL's memory usage and some other common settings. The default values are tuned for a server where MySQL can consume ~512 MB RAM, so you should consider adjusting them to suit your particular server better. 118 | 119 | mysql_server_id: "1" 120 | mysql_max_binlog_size: "100M" 121 | mysql_binlog_format: "ROW" 122 | mysql_expire_logs_days: "10" 123 | mysql_replication_role: '' 124 | mysql_replication_master: '' 125 | mysql_replication_user: {} 126 | 127 | Replication settings. Set `mysql_server_id` and `mysql_replication_role` by server (e.g. the master would be ID `1`, with the `mysql_replication_role` of `master`, and the slave would be ID `2`, with the `mysql_replication_role` of `slave`). The `mysql_replication_user` uses the same keys as individual list items in `mysql_users`, and is created on master servers, and used to replicate on all the slaves. 128 | 129 | `mysql_replication_master` needs to resolve to an IP or a hostname which is accessable to the Slaves (this could be a `/etc/hosts` injection or some other means), otherwise the slaves cannot communicate to the master. 130 | 131 | ### Later versions of MySQL on CentOS 7 132 | 133 | If you want to install MySQL from the official repository instead of installing the system default MariaDB equivalents, you can add the following `pre_tasks` task in your playbook: 134 | 135 | ```yaml 136 | pre_tasks: 137 | - name: Install the MySQL repo. 138 | yum: 139 | name: http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm 140 | state: present 141 | when: ansible_os_family == "RedHat" 142 | 143 | - name: Override variables for MySQL (RedHat). 144 | set_fact: 145 | mysql_daemon: mysqld 146 | mysql_packages: ['mysql-server'] 147 | mysql_log_error: /var/log/mysqld.err 148 | mysql_syslog_tag: mysqld 149 | mysql_pid_file: /var/run/mysqld/mysqld.pid 150 | mysql_socket: /var/lib/mysql/mysql.sock 151 | when: ansible_os_family == "RedHat" 152 | ``` 153 | 154 | ### MariaDB usage 155 | 156 | This role works with either MySQL or a compatible version of MariaDB. On RHEL/CentOS 7+, the mariadb database engine was substituted as the default MySQL replacement package. No modifications are necessary though all of the variables still reference 'mysql' instead of mariadb. 157 | 158 | #### Ubuntu 14.04 and 16.04 MariaDB configuration 159 | 160 | On Ubuntu, the package names are named differently, so the `mysql_package` variable needs to be altered. Set the following variables (at a minimum): 161 | 162 | mysql_packages: 163 | - mariadb-client 164 | - mariadb-server 165 | - python-mysqldb 166 | 167 | ## Dependencies 168 | 169 | None. 170 | 171 | ## Example Playbook 172 | 173 | - hosts: db-servers 174 | become: yes 175 | vars_files: 176 | - vars/main.yml 177 | roles: 178 | - { role: geerlingguy.mysql } 179 | 180 | *Inside `vars/main.yml`*: 181 | 182 | mysql_root_password: super-secure-password 183 | mysql_databases: 184 | - name: example_db 185 | encoding: latin1 186 | collation: latin1_general_ci 187 | mysql_users: 188 | - name: example_user 189 | host: "%" 190 | password: similarly-secure-password 191 | priv: "example_db.*:ALL" 192 | 193 | ## License 194 | 195 | MIT / BSD 196 | 197 | ## Author Information 198 | 199 | This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). 200 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Set this to the user ansible is logging in as - should have root 3 | # or sudo access 4 | mysql_user_home: /root 5 | mysql_user_name: root 6 | mysql_user_password: root 7 | 8 | # The default root user installed by mysql - almost always root 9 | mysql_root_home: /root 10 | mysql_root_username: root 11 | mysql_root_password: root 12 | 13 | # Set this to `true` to forcibly update the root password. 14 | mysql_root_password_update: false 15 | mysql_user_password_update: false 16 | 17 | mysql_enabled_on_startup: true 18 | 19 | # Whether my.cnf should be updated on every run. 20 | overwrite_global_mycnf: true 21 | 22 | # The following variables have a default value depending on operating system. 23 | # mysql_config_file: /etc/my.cnf 24 | # mysql_config_include_dir: /etc/my.cnf.d 25 | 26 | # Pass in a comma-separated list of repos to use (e.g. "remi,epel"). Used only 27 | # for RedHat systems (and derivatives). 28 | mysql_enablerepo: "" 29 | 30 | # Define a custom list of packages to install; if none provided, the default 31 | # package list from vars/[OS-family].yml will be used. 32 | # mysql_packages: 33 | # - mysql 34 | # - mysql-server 35 | # - MySQL-python 36 | 37 | mysql_python_package_debian: python3-mysqldb 38 | 39 | # MySQL connection settings. 40 | mysql_port: "3306" 41 | mysql_bind_address: '0.0.0.0' 42 | mysql_skip_name_resolve: false 43 | mysql_datadir: /var/lib/mysql 44 | mysql_sql_mode: '' 45 | # The following variables have a default value depending on operating system. 46 | # mysql_pid_file: /var/run/mysqld/mysqld.pid 47 | # mysql_socket: /var/lib/mysql/mysql.sock 48 | 49 | # Log file settings. 50 | mysql_log_file_group: mysql 51 | 52 | # Slow query log settings. 53 | mysql_slow_query_log_enabled: false 54 | mysql_slow_query_time: "2" 55 | # The following variable has a default value depending on operating system. 56 | # mysql_slow_query_log_file: /var/log/mysql-slow.log 57 | 58 | # Memory settings (default values optimized ~512MB RAM). 59 | mysql_key_buffer_size: "256M" 60 | mysql_max_allowed_packet: "64M" 61 | mysql_table_open_cache: "256" 62 | mysql_sort_buffer_size: "1M" 63 | mysql_read_buffer_size: "1M" 64 | mysql_read_rnd_buffer_size: "4M" 65 | mysql_myisam_sort_buffer_size: "64M" 66 | mysql_thread_cache_size: "8" 67 | mysql_query_cache_type: "0" 68 | mysql_query_cache_size: "16M" 69 | mysql_query_cache_limit: "1M" 70 | mysql_max_connections: "151" 71 | mysql_tmp_table_size: "16M" 72 | mysql_max_heap_table_size: "16M" 73 | mysql_group_concat_max_len: "1024" 74 | mysql_join_buffer_size: "262144" 75 | 76 | # Other settings. 77 | mysql_lower_case_table_names: "0" 78 | mysql_wait_timeout: "28800" 79 | mysql_event_scheduler_state: "OFF" 80 | 81 | # InnoDB settings. 82 | mysql_innodb_file_per_table: "1" 83 | # Set .._buffer_pool_size up to 80% of RAM but beware of setting too high. 84 | mysql_innodb_buffer_pool_size: "256M" 85 | # Set .._log_file_size to 25% of buffer pool size. 86 | mysql_innodb_log_file_size: "64M" 87 | mysql_innodb_log_buffer_size: "8M" 88 | mysql_innodb_flush_log_at_trx_commit: "1" 89 | mysql_innodb_lock_wait_timeout: "50" 90 | 91 | # These settings require MySQL > 5.5. 92 | mysql_innodb_large_prefix: "1" 93 | mysql_innodb_file_format: "barracuda" 94 | 95 | # mysqldump settings. 96 | mysql_mysqldump_max_allowed_packet: "64M" 97 | 98 | # Logging settings. 99 | mysql_log: "" 100 | # The following variables have a default value depending on operating system. 101 | # mysql_log_error: /var/log/mysql/mysql.err 102 | # mysql_syslog_tag: mysql 103 | 104 | mysql_config_include_files: [] 105 | # - src: path/relative/to/playbook/file.cnf 106 | # - { src: path/relative/to/playbook/anotherfile.cnf, force: yes } 107 | 108 | # Databases. 109 | mysql_databases: [] 110 | # - name: example 111 | # collation: utf8_general_ci 112 | # encoding: utf8 113 | # replicate: 1 114 | 115 | # Users. 116 | mysql_users: [] 117 | # - name: example 118 | # host: 127.0.0.1 119 | # password: secret 120 | # priv: *.*:USAGE 121 | 122 | # Replication settings (replication is only enabled if master/user have values). 123 | mysql_server_id: "1" 124 | mysql_max_binlog_size: "100M" 125 | mysql_binlog_format: "ROW" 126 | mysql_expire_logs_days: "10" 127 | mysql_replication_role: '' 128 | mysql_replication_master: '' 129 | # Same keys as `mysql_users` above. 130 | mysql_replication_user: [] 131 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart mysql 3 | service: "name={{ mysql_daemon }} state=restarted sleep=5" 4 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/meta/.galaxy_install_info: -------------------------------------------------------------------------------- 1 | {install_date: 'Fri Nov 13 01:53:10 2020', version: 3.3.0} 2 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: [] 3 | 4 | galaxy_info: 5 | role_name: mysql 6 | author: geerlingguy 7 | description: MySQL server for RHEL/CentOS and Debian/Ubuntu. 8 | company: "Midwestern Mac, LLC" 9 | license: "license (BSD, MIT)" 10 | min_ansible_version: 2.4 11 | platforms: 12 | - name: EL 13 | versions: 14 | - 6 15 | - 7 16 | - 8 17 | - name: Ubuntu 18 | versions: 19 | - all 20 | - name: Debian 21 | versions: 22 | - all 23 | - name: Archlinux 24 | versions: 25 | - all 26 | galaxy_tags: 27 | - database 28 | - mysql 29 | - mariadb 30 | - db 31 | - sql 32 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | roles: 7 | - role: geerlingguy.mysql 8 | 9 | post_tasks: 10 | - name: Make sure we can connect to MySQL via Unix socket. 11 | command: "mysql -u root -proot -e 'show databases;'" 12 | changed_when: false 13 | 14 | - name: Make sure we can connect to MySQL via TCP. 15 | command: "mysql -u root -proot -h 127.0.0.1 -e 'show databases;'" 16 | changed_when: false 17 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: docker 6 | lint: | 7 | set -e 8 | yamllint . 9 | ansible-lint 10 | platforms: 11 | - name: instance 12 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" 13 | command: ${MOLECULE_DOCKER_COMMAND:-""} 14 | volumes: 15 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 16 | privileged: true 17 | pre_build_image: true 18 | provisioner: 19 | name: ansible 20 | playbooks: 21 | converge: ${MOLECULE_PLAYBOOK:-converge.yml} 22 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/configure.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Get MySQL version. 3 | command: 'mysql --version' 4 | register: mysql_cli_version 5 | changed_when: false 6 | check_mode: false 7 | 8 | - name: Copy my.cnf global MySQL configuration. 9 | template: 10 | src: my.cnf.j2 11 | dest: "{{ mysql_config_file }}" 12 | owner: root 13 | group: root 14 | mode: 0644 15 | force: "{{ overwrite_global_mycnf }}" 16 | notify: restart mysql 17 | 18 | - name: Verify mysql include directory exists. 19 | file: 20 | path: "{{ mysql_config_include_dir }}" 21 | state: directory 22 | owner: root 23 | group: root 24 | mode: 0755 25 | when: mysql_config_include_files | length 26 | 27 | - name: Copy my.cnf override files into include directory. 28 | template: 29 | src: "{{ item.src }}" 30 | dest: "{{ mysql_config_include_dir }}/{{ item.src | basename }}" 31 | owner: root 32 | group: root 33 | mode: 0644 34 | force: "{{ item.force | default(False) }}" 35 | with_items: "{{ mysql_config_include_files }}" 36 | notify: restart mysql 37 | 38 | - name: Create slow query log file (if configured). 39 | command: "touch {{ mysql_slow_query_log_file }}" 40 | args: 41 | creates: "{{ mysql_slow_query_log_file }}" 42 | warn: false 43 | when: mysql_slow_query_log_enabled 44 | 45 | - name: Create datadir if it does not exist 46 | file: 47 | path: "{{ mysql_datadir }}" 48 | state: directory 49 | owner: mysql 50 | group: mysql 51 | mode: 0755 52 | setype: mysqld_db_t 53 | 54 | - name: Set ownership on slow query log file (if configured). 55 | file: 56 | path: "{{ mysql_slow_query_log_file }}" 57 | state: file 58 | owner: mysql 59 | group: "{{ mysql_log_file_group }}" 60 | mode: 0640 61 | when: mysql_slow_query_log_enabled 62 | 63 | - name: Create error log file (if configured). 64 | command: "touch {{ mysql_log_error }}" 65 | args: 66 | creates: "{{ mysql_log_error }}" 67 | warn: false 68 | when: 69 | - mysql_log | default(true) 70 | - mysql_log_error | default(false) 71 | tags: ['skip_ansible_galaxy'] 72 | 73 | - name: Set ownership on error log file (if configured). 74 | file: 75 | path: "{{ mysql_log_error }}" 76 | state: file 77 | owner: mysql 78 | group: "{{ mysql_log_file_group }}" 79 | mode: 0640 80 | when: 81 | - mysql_log | default(true) 82 | - mysql_log_error | default(false) 83 | tags: ['skip_ansible_galaxy'] 84 | 85 | - name: Ensure MySQL is started and enabled on boot. 86 | service: "name={{ mysql_daemon }} state=started enabled={{ mysql_enabled_on_startup }}" 87 | register: mysql_service_configuration 88 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/databases.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure MySQL databases are present. 3 | mysql_db: 4 | name: "{{ item.name }}" 5 | collation: "{{ item.collation | default('utf8_general_ci') }}" 6 | encoding: "{{ item.encoding | default('utf8') }}" 7 | state: "{{ item.state | default('present') }}" 8 | with_items: "{{ mysql_databases }}" 9 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Variable configuration. 3 | - include_tasks: variables.yml 4 | 5 | # Setup/install tasks. 6 | - include_tasks: setup-RedHat.yml 7 | when: ansible_os_family == 'RedHat' 8 | 9 | - include_tasks: setup-Debian.yml 10 | when: ansible_os_family == 'Debian' 11 | 12 | - include_tasks: setup-Archlinux.yml 13 | when: ansible_os_family == 'Archlinux' 14 | 15 | - name: Check if MySQL packages were installed. 16 | set_fact: 17 | mysql_install_packages: "{{ (rh_mysql_install_packages is defined and rh_mysql_install_packages.changed) 18 | or (deb_mysql_install_packages is defined and deb_mysql_install_packages.changed) 19 | or (arch_mysql_install_packages is defined and arch_mysql_install_packages.changed) }}" 20 | 21 | # Configure MySQL. 22 | - include_tasks: configure.yml 23 | - include_tasks: secure-installation.yml 24 | - include_tasks: databases.yml 25 | - include_tasks: users.yml 26 | - include_tasks: replication.yml 27 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/replication.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure replication user exists on master. 3 | mysql_user: 4 | name: "{{ mysql_replication_user.name }}" 5 | host: "{{ mysql_replication_user.host | default('%') }}" 6 | password: "{{ mysql_replication_user.password }}" 7 | priv: "{{ mysql_replication_user.priv | default('*.*:REPLICATION SLAVE,REPLICATION CLIENT') }}" 8 | state: present 9 | when: 10 | - mysql_replication_role == 'master' 11 | - mysql_replication_user.name is defined 12 | - (mysql_replication_master | length) > 0 13 | tags: ['skip_ansible_galaxy'] 14 | 15 | - name: Check slave replication status. 16 | mysql_replication: 17 | mode: getslave 18 | login_user: "{{ mysql_replication_user.name }}" 19 | login_password: "{{ mysql_replication_user.password }}" 20 | ignore_errors: true 21 | register: slave 22 | when: 23 | - mysql_replication_role == 'slave' 24 | - (mysql_replication_master | length) > 0 25 | tags: ['skip_ansible_galaxy'] 26 | 27 | - name: Check master replication status. 28 | mysql_replication: mode=getmaster 29 | delegate_to: "{{ mysql_replication_master }}" 30 | register: master 31 | when: 32 | - (slave.Is_Slave is defined and not slave.Is_Slave) or (slave.Is_Slave is not defined and slave is failed) 33 | - mysql_replication_role == 'slave' 34 | - (mysql_replication_master | length) > 0 35 | tags: ['skip_ansible_galaxy'] 36 | 37 | - name: Configure replication on the slave. 38 | mysql_replication: 39 | mode: changemaster 40 | master_host: "{{ mysql_replication_master }}" 41 | master_user: "{{ mysql_replication_user.name }}" 42 | master_password: "{{ mysql_replication_user.password }}" 43 | master_log_file: "{{ master.File }}" 44 | master_log_pos: "{{ master.Position }}" 45 | ignore_errors: true 46 | when: 47 | - (slave.Is_Slave is defined and not slave.Is_Slave) or (slave.Is_Slave is not defined and slave is failed) 48 | - mysql_replication_role == 'slave' 49 | - mysql_replication_user.name is defined 50 | - (mysql_replication_master | length) > 0 51 | 52 | - name: Start replication. 53 | mysql_replication: mode=startslave 54 | when: 55 | - (slave.Is_Slave is defined and not slave.Is_Slave) or (slave.Is_Slave is not defined and slave is failed) 56 | - mysql_replication_role == 'slave' 57 | - (mysql_replication_master | length) > 0 58 | tags: ['skip_ansible_galaxy'] 59 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/secure-installation.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure default user is present. 3 | mysql_user: 4 | name: "{{ mysql_user_name }}" 5 | host: 'localhost' 6 | password: "{{ mysql_user_password }}" 7 | priv: '*.*:ALL,GRANT' 8 | state: present 9 | when: mysql_user_name != mysql_root_username 10 | 11 | # Has to be after the password assignment, for idempotency. 12 | - name: Copy user-my.cnf file with password credentials. 13 | template: 14 | src: "user-my.cnf.j2" 15 | dest: "{{ mysql_user_home }}/.my.cnf" 16 | owner: "{{ mysql_user_name }}" 17 | mode: 0600 18 | when: > 19 | mysql_user_name != mysql_root_username 20 | and (mysql_install_packages | bool or mysql_user_password_update) 21 | 22 | - name: Disallow root login remotely 23 | command: 'mysql -NBe "{{ item }}"' 24 | with_items: 25 | - DELETE FROM mysql.user WHERE User='{{ mysql_root_username }}' AND Host NOT IN ('localhost', '127.0.0.1', '::1') 26 | changed_when: false 27 | 28 | - name: Get list of hosts for the root user. 29 | command: mysql -NBe 30 | "SELECT Host 31 | FROM mysql.user 32 | WHERE User = '{{ mysql_root_username }}' 33 | ORDER BY (Host='localhost') ASC" 34 | register: mysql_root_hosts 35 | changed_when: false 36 | check_mode: false 37 | when: mysql_install_packages | bool or mysql_root_password_update 38 | 39 | # Note: We do not use mysql_user for this operation, as it doesn't always update 40 | # the root password correctly. See: https://goo.gl/MSOejW 41 | # Set root password for MySQL >= 5.7.x. 42 | - name: Update MySQL root password for localhost root account (5.7.x). 43 | shell: > 44 | mysql -u root -NBe 45 | 'ALTER USER "{{ mysql_root_username }}"@"{{ item }}" 46 | IDENTIFIED WITH mysql_native_password BY "{{ mysql_root_password }}";' 47 | with_items: "{{ mysql_root_hosts.stdout_lines|default([]) }}" 48 | when: > 49 | ((mysql_install_packages | bool) or mysql_root_password_update) 50 | and ('5.7.' in mysql_cli_version.stdout or '8.0.' in mysql_cli_version.stdout) 51 | 52 | # Set root password for MySQL < 5.7.x. 53 | - name: Update MySQL root password for localhost root account (< 5.7.x). 54 | shell: > 55 | mysql -NBe 56 | 'SET PASSWORD FOR "{{ mysql_root_username }}"@"{{ item }}" = PASSWORD("{{ mysql_root_password }}");' 57 | with_items: "{{ mysql_root_hosts.stdout_lines|default([]) }}" 58 | when: > 59 | ((mysql_install_packages | bool) or mysql_root_password_update) 60 | and ('5.7.' not in mysql_cli_version.stdout and '8.0.' not in mysql_cli_version.stdout) 61 | 62 | # Has to be after the root password assignment, for idempotency. 63 | - name: Copy .my.cnf file with root password credentials. 64 | template: 65 | src: "root-my.cnf.j2" 66 | dest: "{{ mysql_root_home }}/.my.cnf" 67 | owner: root 68 | group: root 69 | mode: 0600 70 | when: mysql_install_packages | bool or mysql_root_password_update 71 | 72 | - name: Get list of hosts for the anonymous user. 73 | command: mysql -NBe 'SELECT Host FROM mysql.user WHERE User = ""' 74 | register: mysql_anonymous_hosts 75 | changed_when: false 76 | check_mode: false 77 | 78 | - name: Remove anonymous MySQL users. 79 | mysql_user: 80 | name: "" 81 | host: "{{ item }}" 82 | state: absent 83 | with_items: "{{ mysql_anonymous_hosts.stdout_lines|default([]) }}" 84 | 85 | - name: Remove MySQL test database. 86 | mysql_db: "name='test' state=absent" 87 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/setup-Archlinux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure MySQL Python libraries are installed. 3 | pacman: "name=mysql-python state=present" 4 | 5 | - name: Ensure MySQL packages are installed. 6 | pacman: "name={{ mysql_packages }} state=present" 7 | register: arch_mysql_install_packages 8 | 9 | - name: Run mysql_install_db if MySQL packages were changed. 10 | command: mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql 11 | when: arch_mysql_install_packages.changed 12 | tags: ['skip_ansible_lint'] 13 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/setup-Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if MySQL is already installed. 3 | stat: path=/etc/init.d/mysql 4 | register: mysql_installed 5 | 6 | - name: Update apt cache if MySQL is not yet installed. 7 | apt: update_cache=yes 8 | when: not mysql_installed.stat.exists 9 | 10 | - name: Ensure MySQL Python libraries are installed. 11 | apt: 12 | name: "{{ mysql_python_package_debian }}" 13 | state: present 14 | 15 | - name: Ensure MySQL packages are installed. 16 | apt: 17 | name: "{{ mysql_packages }}" 18 | state: present 19 | register: deb_mysql_install_packages 20 | 21 | # Because Ubuntu starts MySQL as part of the install process, we need to stop 22 | # mysql and remove the logfiles in case the user set a custom log file size. 23 | - name: Ensure MySQL is stopped after initial install. 24 | service: "name={{ mysql_daemon }} state=stopped" 25 | when: not mysql_installed.stat.exists 26 | 27 | - name: Delete innodb log files created by apt package after initial install. 28 | file: path={{ mysql_datadir }}/{{ item }} state=absent 29 | with_items: 30 | - ib_logfile0 31 | - ib_logfile1 32 | when: not mysql_installed.stat.exists 33 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/setup-RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure MySQL packages are installed. 3 | yum: 4 | name: "{{ mysql_packages }}" 5 | state: present 6 | enablerepo: "{{ mysql_enablerepo | default(omit, true) }}" 7 | register: rh_mysql_install_packages 8 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/users.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure MySQL users are present. 3 | mysql_user: 4 | name: "{{ item.name }}" 5 | host: "{{ item.host | default('localhost') }}" 6 | password: "{{ item.password }}" 7 | priv: "{{ item.priv | default('*.*:USAGE') }}" 8 | state: "{{ item.state | default('present') }}" 9 | append_privs: "{{ item.append_privs | default('no') }}" 10 | encrypted: "{{ item.encrypted | default('no') }}" 11 | with_items: "{{ mysql_users }}" 12 | no_log: true 13 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/tasks/variables.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Variable configuration. 3 | - name: Include OS-specific variables. 4 | include_vars: "{{ item }}" 5 | with_first_found: 6 | - files: 7 | - "vars/{{ ansible_os_family }}-{{ ansible_distribution_major_version }}.yml" 8 | - "vars/{{ ansible_os_family }}.yml" 9 | skip: true 10 | 11 | - name: Define mysql_packages. 12 | set_fact: 13 | mysql_packages: "{{ __mysql_packages | list }}" 14 | when: mysql_packages is not defined 15 | 16 | - name: Define mysql_daemon. 17 | set_fact: 18 | mysql_daemon: "{{ __mysql_daemon }}" 19 | when: mysql_daemon is not defined 20 | 21 | - name: Define mysql_slow_query_log_file. 22 | set_fact: 23 | mysql_slow_query_log_file: "{{ __mysql_slow_query_log_file }}" 24 | when: mysql_slow_query_log_file is not defined 25 | 26 | - name: Define mysql_log_error. 27 | set_fact: 28 | mysql_log_error: "{{ __mysql_log_error }}" 29 | when: mysql_log_error is not defined 30 | 31 | - name: Define mysql_syslog_tag. 32 | set_fact: 33 | mysql_syslog_tag: "{{ __mysql_syslog_tag }}" 34 | when: mysql_syslog_tag is not defined 35 | 36 | - name: Define mysql_pid_file. 37 | set_fact: 38 | mysql_pid_file: "{{ __mysql_pid_file }}" 39 | when: mysql_pid_file is not defined 40 | 41 | - name: Define mysql_config_file. 42 | set_fact: 43 | mysql_config_file: "{{ __mysql_config_file }}" 44 | when: mysql_config_file is not defined 45 | 46 | - name: Define mysql_config_include_dir. 47 | set_fact: 48 | mysql_config_include_dir: "{{ __mysql_config_include_dir }}" 49 | when: mysql_config_include_dir is not defined 50 | 51 | - name: Define mysql_socket. 52 | set_fact: 53 | mysql_socket: "{{ __mysql_socket }}" 54 | when: mysql_socket is not defined 55 | 56 | - name: Define mysql_supports_innodb_large_prefix. 57 | set_fact: 58 | mysql_supports_innodb_large_prefix: "{{ __mysql_supports_innodb_large_prefix }}" 59 | when: mysql_supports_innodb_large_prefix is not defined 60 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/templates/my.cnf.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | [client] 4 | #password = your_password 5 | port = {{ mysql_port }} 6 | socket = {{ mysql_socket }} 7 | 8 | [mysqld] 9 | port = {{ mysql_port }} 10 | bind-address = {{ mysql_bind_address }} 11 | datadir = {{ mysql_datadir }} 12 | socket = {{ mysql_socket }} 13 | pid-file = {{ mysql_pid_file }} 14 | {% if mysql_skip_name_resolve %} 15 | skip-name-resolve 16 | {% endif %} 17 | {% if mysql_sql_mode %} 18 | sql_mode = {{ mysql_sql_mode }} 19 | {% endif %} 20 | 21 | # Logging configuration. 22 | {% if mysql_log_error == 'syslog' or mysql_log == 'syslog' %} 23 | syslog 24 | syslog-tag = {{ mysql_syslog_tag }} 25 | {% else %} 26 | {% if mysql_log %} 27 | log = {{ mysql_log }} 28 | {% endif %} 29 | log-error = {{ mysql_log_error }} 30 | {% endif %} 31 | 32 | {% if mysql_slow_query_log_enabled %} 33 | # Slow query log configuration. 34 | slow_query_log = 1 35 | slow_query_log_file = {{ mysql_slow_query_log_file }} 36 | long_query_time = {{ mysql_slow_query_time }} 37 | {% endif %} 38 | 39 | {% if mysql_replication_master %} 40 | # Replication 41 | server-id = {{ mysql_server_id }} 42 | 43 | {% if mysql_replication_role == 'master' %} 44 | log_bin = mysql-bin 45 | log-bin-index = mysql-bin.index 46 | expire_logs_days = {{ mysql_expire_logs_days }} 47 | max_binlog_size = {{ mysql_max_binlog_size }} 48 | binlog_format = {{mysql_binlog_format}} 49 | 50 | {% for db in mysql_databases %} 51 | {% if db.replicate|default(1) %} 52 | binlog_do_db = {{ db.name }} 53 | {% else %} 54 | binlog_ignore_db = {{ db.name }} 55 | {% endif %} 56 | {% endfor %} 57 | {% endif %} 58 | 59 | {% if mysql_replication_role == 'slave' %} 60 | read_only 61 | relay-log = relay-bin 62 | relay-log-index = relay-bin.index 63 | {% endif %} 64 | {% endif %} 65 | 66 | # Disabling symbolic-links is recommended to prevent assorted security risks 67 | symbolic-links = 0 68 | 69 | # User is ignored when systemd is used (fedora >= 15). 70 | user = mysql 71 | 72 | # http://dev.mysql.com/doc/refman/5.5/en/performance-schema.html 73 | ;performance_schema 74 | 75 | # Memory settings. 76 | key_buffer_size = {{ mysql_key_buffer_size }} 77 | max_allowed_packet = {{ mysql_max_allowed_packet }} 78 | table_open_cache = {{ mysql_table_open_cache }} 79 | sort_buffer_size = {{ mysql_sort_buffer_size }} 80 | read_buffer_size = {{ mysql_read_buffer_size }} 81 | read_rnd_buffer_size = {{ mysql_read_rnd_buffer_size }} 82 | myisam_sort_buffer_size = {{ mysql_myisam_sort_buffer_size }} 83 | thread_cache_size = {{ mysql_thread_cache_size }} 84 | {% if '8.0.' not in mysql_cli_version.stdout %} 85 | query_cache_type = {{ mysql_query_cache_type }} 86 | query_cache_size = {{ mysql_query_cache_size }} 87 | query_cache_limit = {{ mysql_query_cache_limit }} 88 | {% endif %} 89 | max_connections = {{ mysql_max_connections }} 90 | tmp_table_size = {{ mysql_tmp_table_size }} 91 | max_heap_table_size = {{ mysql_max_heap_table_size }} 92 | group_concat_max_len = {{ mysql_group_concat_max_len }} 93 | join_buffer_size = {{ mysql_join_buffer_size }} 94 | 95 | # Other settings. 96 | wait_timeout = {{ mysql_wait_timeout }} 97 | lower_case_table_names = {{ mysql_lower_case_table_names }} 98 | event_scheduler = {{ mysql_event_scheduler_state }} 99 | 100 | # InnoDB settings. 101 | {% if mysql_supports_innodb_large_prefix and '8.0.' not in mysql_cli_version.stdout %} 102 | innodb_large_prefix = {{ mysql_innodb_large_prefix }} 103 | innodb_file_format = {{ mysql_innodb_file_format }} 104 | {% endif %} 105 | innodb_file_per_table = {{ mysql_innodb_file_per_table }} 106 | innodb_buffer_pool_size = {{ mysql_innodb_buffer_pool_size }} 107 | innodb_log_file_size = {{ mysql_innodb_log_file_size }} 108 | innodb_log_buffer_size = {{ mysql_innodb_log_buffer_size }} 109 | innodb_flush_log_at_trx_commit = {{ mysql_innodb_flush_log_at_trx_commit }} 110 | innodb_lock_wait_timeout = {{ mysql_innodb_lock_wait_timeout }} 111 | 112 | [mysqldump] 113 | quick 114 | max_allowed_packet = {{ mysql_mysqldump_max_allowed_packet }} 115 | 116 | [mysqld_safe] 117 | pid-file = {{ mysql_pid_file }} 118 | 119 | {% if mysql_config_include_files | length %} 120 | # * IMPORTANT: Additional settings that can override those from this file! 121 | # The files must end with '.cnf', otherwise they'll be ignored. 122 | # 123 | !includedir {{ mysql_config_include_dir }} 124 | {% endif %} 125 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/templates/root-my.cnf.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | [client] 4 | user="{{ mysql_root_username }}" 5 | password="{{ mysql_root_password }}" 6 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/templates/user-my.cnf.j2: -------------------------------------------------------------------------------- 1 | {{ ansible_managed | comment }} 2 | 3 | [client] 4 | user="{{ mysql_user_name }}" 5 | password="{{ mysql_user_password }}" 6 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/vars/Archlinux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __mysql_daemon: mariadb 3 | __mysql_packages: 4 | - mariadb 5 | __mysql_slow_query_log_file: /var/log/mysql/mysql-slow.log 6 | __mysql_log_error: /var/log/mysql.err 7 | __mysql_syslog_tag: mysql 8 | __mysql_pid_file: /run/mysqld/mysqld.pid 9 | __mysql_config_file: /etc/mysql/my.cnf 10 | __mysql_config_include_dir: /etc/mysql/conf.d 11 | __mysql_socket: /run/mysqld/mysqld.sock 12 | __mysql_supports_innodb_large_prefix: true 13 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/vars/Debian-10.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __mysql_daemon: mariadb 3 | __mysql_packages: 4 | - default-mysql-server 5 | mysql_log_file_group: adm 6 | __mysql_slow_query_log_file: /var/log/mysql/mysql-slow.log 7 | __mysql_log_error: /var/log/mysql/mysql.log 8 | __mysql_syslog_tag: mariadb 9 | __mysql_pid_file: /run/mysqld/mysqld.pid 10 | __mysql_config_file: /etc/mysql/my.cnf 11 | __mysql_config_include_dir: /etc/mysql/conf.d 12 | __mysql_socket: /run/mysqld/mysqld.sock 13 | __mysql_supports_innodb_large_prefix: true 14 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/vars/Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __mysql_daemon: mysql 3 | __mysql_packages: 4 | - mysql-common 5 | - mysql-server 6 | mysql_log_file_group: adm 7 | __mysql_slow_query_log_file: /var/log/mysql/mysql-slow.log 8 | __mysql_log_error: /var/log/mysql/mysql.err 9 | __mysql_syslog_tag: mysql 10 | __mysql_pid_file: /var/run/mysqld/mysqld.pid 11 | __mysql_config_file: /etc/mysql/my.cnf 12 | __mysql_config_include_dir: /etc/mysql/conf.d 13 | __mysql_socket: /var/run/mysqld/mysqld.sock 14 | __mysql_supports_innodb_large_prefix: true 15 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/vars/RedHat-6.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __mysql_daemon: mysqld 3 | __mysql_packages: 4 | - mysql 5 | - mysql-server 6 | - MySQL-python 7 | __mysql_slow_query_log_file: /var/log/mysql-slow.log 8 | __mysql_log_error: /var/log/mysql.err 9 | __mysql_syslog_tag: mysql 10 | __mysql_pid_file: /var/run/mysqld/mysqld.pid 11 | __mysql_config_file: /etc/my.cnf 12 | __mysql_config_include_dir: /etc/my.cnf.d 13 | __mysql_socket: /var/lib/mysql/mysql.sock 14 | __mysql_supports_innodb_large_prefix: false 15 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/vars/RedHat-7.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __mysql_daemon: mariadb 3 | __mysql_packages: 4 | - mariadb 5 | - mariadb-server 6 | - mariadb-libs 7 | - MySQL-python 8 | - perl-DBD-MySQL 9 | __mysql_slow_query_log_file: /var/log/mysql-slow.log 10 | __mysql_log_error: /var/log/mariadb/mariadb.log 11 | __mysql_syslog_tag: mariadb 12 | __mysql_pid_file: /var/run/mariadb/mariadb.pid 13 | __mysql_config_file: /etc/my.cnf 14 | __mysql_config_include_dir: /etc/my.cnf.d 15 | __mysql_socket: /var/lib/mysql/mysql.sock 16 | __mysql_supports_innodb_large_prefix: true 17 | -------------------------------------------------------------------------------- /roles/geerlingguy.mysql/vars/RedHat-8.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __mysql_daemon: mariadb 3 | __mysql_packages: 4 | - mariadb 5 | - mariadb-server 6 | - mariadb-connector-c 7 | - python3-PyMySQL 8 | - perl-DBD-MySQL 9 | __mysql_slow_query_log_file: /var/log/mysql-slow.log 10 | __mysql_log_error: /var/log/mariadb/mariadb.log 11 | __mysql_syslog_tag: mariadb 12 | __mysql_pid_file: /var/run/mariadb/mariadb.pid 13 | __mysql_config_file: /etc/my.cnf 14 | __mysql_config_include_dir: /etc/my.cnf.d 15 | __mysql_socket: /var/lib/mysql/mysql.sock 16 | # The entries controlled by this value should not be used with MariaDB >= 10.2.2 17 | # See https://github.com/frappe/bench/issues/681#issuecomment-398984706 18 | __mysql_supports_innodb_large_prefix: false 19 | -------------------------------------------------------------------------------- /roles/httpd-role/.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/ -------------------------------------------------------------------------------- /roles/httpd-role/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 | -------------------------------------------------------------------------------- /roles/httpd-role/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for httpd-role 3 | 4 | sysadmin: elliot@linuxhandbook.com 5 | -------------------------------------------------------------------------------- /roles/httpd-role/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for httpd-role -------------------------------------------------------------------------------- /roles/httpd-role/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: your name 3 | description: your role 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 | # Choose a valid license ID from https://spdx.org - some suggested licenses: 11 | # - BSD-3-Clause (default) 12 | # - MIT 13 | # - GPL-2.0-or-later 14 | # - GPL-3.0-only 15 | # - Apache-2.0 16 | # - CC-BY-4.0 17 | license: license (GPL-2.0-or-later, MIT, etc) 18 | 19 | min_ansible_version: 2.9 20 | 21 | # If this a Container Enabled role, provide the minimum Ansible Container version. 22 | # min_ansible_container_version: 23 | 24 | # 25 | # Provide a list of supported platforms, and for each platform a list of versions. 26 | # If you don't wish to enumerate all versions for a particular platform, use 'all'. 27 | # To view available platforms and versions (or releases), visit: 28 | # https://galaxy.ansible.com/api/v1/platforms/ 29 | # 30 | # platforms: 31 | # - name: Fedora 32 | # versions: 33 | # - all 34 | # - 25 35 | # - name: SomePlatform 36 | # versions: 37 | # - all 38 | # - 1.0 39 | # - 7 40 | # - 99.99 41 | 42 | galaxy_tags: [] 43 | # List tags for your role here, one per line. A tag is a keyword that describes 44 | # and categorizes the role. Users find roles by searching for tags. Be sure to 45 | # remove the '[]' above, if you add tags to this list. 46 | # 47 | # NOTE: A tag is limited to a single word comprised of alphanumeric characters. 48 | # Maximum 20 tags per role. 49 | 50 | dependencies: [] 51 | # List your role dependencies here, one per line. Be sure to remove the '[]' above, 52 | # if you add dependencies to this list. 53 | -------------------------------------------------------------------------------- /roles/httpd-role/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for httpd-role 3 | 4 | - name: Install httpd 5 | yum: 6 | name: httpd 7 | state: latest 8 | 9 | - name: Start and enable httpd 10 | service: 11 | name: httpd 12 | state: started 13 | enabled: true 14 | 15 | - name: Create index.html using Jinja2 16 | template: 17 | src: index.j2 18 | dest: /var/www/html/index.html 19 | -------------------------------------------------------------------------------- /roles/httpd-role/templates/index.j2: -------------------------------------------------------------------------------- 1 | Welcome to {{ inventory_hostname }} 2 | 3 | This is an Apache Web Server. 4 | 5 | Please contact the {{ sysadmin }} for any questions or concerns. 6 | -------------------------------------------------------------------------------- /roles/httpd-role/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /roles/httpd-role/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - httpd-role -------------------------------------------------------------------------------- /roles/httpd-role/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for httpd-role -------------------------------------------------------------------------------- /roles/jenkins_role/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | --- 3 | github: geerlingguy 4 | patreon: geerlingguy 5 | -------------------------------------------------------------------------------- /roles/jenkins_role/.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-stale - https://github.com/probot/stale 2 | 3 | # Number of days of inactivity before an Issue or Pull Request becomes stale 4 | daysUntilStale: 90 5 | 6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed. 7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 8 | daysUntilClose: 30 9 | 10 | # Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled) 11 | onlyLabels: [] 12 | 13 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 14 | exemptLabels: 15 | - pinned 16 | - security 17 | - planned 18 | 19 | # Set to true to ignore issues in a project (defaults to false) 20 | exemptProjects: false 21 | 22 | # Set to true to ignore issues in a milestone (defaults to false) 23 | exemptMilestones: false 24 | 25 | # Set to true to ignore issues with an assignee (defaults to false) 26 | exemptAssignees: false 27 | 28 | # Label to use when marking as stale 29 | staleLabel: stale 30 | 31 | # Limit the number of actions per hour, from 1-30. Default is 30 32 | limitPerRun: 30 33 | 34 | pulls: 35 | markComment: |- 36 | This pull request has been marked 'stale' due to lack of recent activity. If there is no further activity, the PR will be closed in another 30 days. Thank you for your contribution! 37 | 38 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark pull requests as stale. 39 | 40 | unmarkComment: >- 41 | This pull request is no longer marked for closure. 42 | 43 | closeComment: >- 44 | This pull request has been closed due to inactivity. If you feel this is in error, please reopen the pull request or file a new PR with the relevant details. 45 | 46 | issues: 47 | markComment: |- 48 | This issue has been marked 'stale' due to lack of recent activity. If there is no further activity, the issue will be closed in another 30 days. Thank you for your contribution! 49 | 50 | Please read [this blog post](https://www.jeffgeerling.com/blog/2020/enabling-stale-issue-bot-on-my-github-repositories) to see the reasons why I mark issues as stale. 51 | 52 | unmarkComment: >- 53 | This issue is no longer marked for closure. 54 | 55 | closeComment: >- 56 | This issue has been closed due to inactivity. If you feel this is in error, please reopen the issue or file a new issue with the relevant details. 57 | -------------------------------------------------------------------------------- /roles/jenkins_role/.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | */__pycache__ 3 | *.pyc 4 | -------------------------------------------------------------------------------- /roles/jenkins_role/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | services: docker 4 | 5 | env: 6 | global: 7 | - ROLE_NAME: jenkins 8 | matrix: 9 | # Test defaults. 10 | - MOLECULE_DISTRO: centos8 11 | - MOLECULE_DISTRO: ubuntu1804 12 | - MOLECULE_DISTRO: ubuntu1604 13 | - MOLECULE_DISTRO: debian10 14 | 15 | # Test other role features. 16 | - MOLECULE_DISTRO: ubuntu1804 17 | MOLECULE_PLAYBOOK: playbook-http-port.yml 18 | 19 | - MOLECULE_DISTRO: ubuntu1804 20 | MOLECULE_PLAYBOOK: playbook-prefix.yml 21 | 22 | - MOLECULE_DISTRO: centos7 23 | MOLECULE_PLAYBOOK: playbook-jenkins-version.yml 24 | 25 | - MOLECULE_DISTRO: ubuntu1804 26 | MOLECULE_PLAYBOOK: playbook-plugins-with-home.yml 27 | 28 | install: 29 | # Install test dependencies. 30 | - pip install molecule yamllint ansible-lint docker 31 | 32 | before_script: 33 | # Use actual Ansible Galaxy role name for the project directory. 34 | - cd ../ 35 | - mv ansible-role-$ROLE_NAME geerlingguy.$ROLE_NAME 36 | - cd geerlingguy.$ROLE_NAME 37 | 38 | script: 39 | # Run tests. 40 | - molecule test 41 | 42 | notifications: 43 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 44 | -------------------------------------------------------------------------------- /roles/jenkins_role/.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | rules: 4 | line-length: 5 | max: 150 6 | level: warning 7 | -------------------------------------------------------------------------------- /roles/jenkins_role/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Jeff Geerling 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /roles/jenkins_role/README.md: -------------------------------------------------------------------------------- 1 | # Ansible Role: Jenkins CI 2 | 3 | [![Build Status](https://travis-ci.org/geerlingguy/ansible-role-jenkins.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-jenkins) 4 | 5 | Installs Jenkins CI on RHEL/CentOS and Debian/Ubuntu servers. 6 | 7 | ## Requirements 8 | 9 | Requires `curl` to be installed on the server. Also, newer versions of Jenkins require Java 8+ (see the test playbooks inside the `molecule/default` directory for an example of how to use newer versions of Java for your OS). 10 | 11 | ## Role Variables 12 | 13 | Available variables are listed below, along with default values (see `defaults/main.yml`): 14 | 15 | jenkins_package_state: present 16 | 17 | The state of the `jenkins` package install. By default this role installs Jenkins but will not upgrade Jenkins (when using package-based installs). If you want to always update to the latest version, change this to `latest`. 18 | 19 | jenkins_hostname: localhost 20 | 21 | The system hostname; usually `localhost` works fine. This will be used during setup to communicate with the running Jenkins instance via HTTP requests. 22 | 23 | jenkins_home: /var/lib/jenkins 24 | 25 | The Jenkins home directory which, amongst others, is being used for storing artifacts, workspaces and plugins. This variable allows you to override the default `/var/lib/jenkins` location. 26 | 27 | jenkins_http_port: 8080 28 | 29 | The HTTP port for Jenkins' web interface. 30 | 31 | jenkins_admin_username: admin 32 | jenkins_admin_password: admin 33 | 34 | Default admin account credentials which will be created the first time Jenkins is installed. 35 | 36 | jenkins_admin_password_file: "" 37 | 38 | Default admin password file which will be created the first time Jenkins is installed as /var/lib/jenkins/secrets/initialAdminPassword 39 | 40 | jenkins_jar_location: /opt/jenkins-cli.jar 41 | 42 | The location at which the `jenkins-cli.jar` jarfile will be kept. This is used for communicating with Jenkins via the CLI. 43 | 44 | jenkins_plugins: 45 | - blueocean 46 | - name: influxdb 47 | version: "1.12.1" 48 | 49 | Jenkins plugins to be installed automatically during provisioning. Defaults to empty list (`[]`). Items can use name or dictionary with `name` and `version` keys to pin specific version of a plugin. 50 | 51 | jenkins_plugins_install_dependencies: true 52 | 53 | Whether Jenkins plugins to be installed should also install any plugin dependencies. 54 | 55 | jenkins_plugins_state: present 56 | 57 | Use `latest` to ensure all plugins are running the most up-to-date version. For any plugin that has a specific version set in `jenkins_plugins` list, state `present` will be used instead of `jenkins_plugins_state` value. 58 | 59 | jenkins_plugin_updates_expiration: 86400 60 | 61 | Number of seconds after which a new copy of the update-center.json file is downloaded. Set it to 0 if no cache file should be used. 62 | 63 | jenkins_updates_url: "https://updates.jenkins.io" 64 | 65 | The URL to use for Jenkins plugin updates and update-center information. 66 | 67 | jenkins_plugin_timeout: 30 68 | 69 | The server connection timeout, in seconds, when installing Jenkins plugins. 70 | 71 | jenkins_version: "2.220" 72 | jenkins_pkg_url: "http://www.example.com" 73 | 74 | (Optional) Then Jenkins version can be pinned to any version available on `http://pkg.jenkins-ci.org/debian/` (Debian/Ubuntu) or `http://pkg.jenkins-ci.org/redhat/` (RHEL/CentOS). If the Jenkins version you need is not available in the default package URLs, you can override the URL with your own; set `jenkins_pkg_url` (_Note_: the role depends on the same naming convention that `http://pkg.jenkins-ci.org/` uses). 75 | 76 | jenkins_url_prefix: "" 77 | 78 | Used for setting a URL prefix for your Jenkins installation. The option is added as `--prefix={{ jenkins_url_prefix }}` to the Jenkins initialization `java` invocation, so you can access the installation at a path like `http://www.example.com{{ jenkins_url_prefix }}`. Make sure you start the prefix with a `/` (e.g. `/jenkins`). 79 | 80 | jenkins_connection_delay: 5 81 | jenkins_connection_retries: 60 82 | 83 | Amount of time and number of times to wait when connecting to Jenkins after initial startup, to verify that Jenkins is running. Total time to wait = `delay` * `retries`, so by default this role will wait up to 300 seconds before timing out. 84 | 85 | jenkins_prefer_lts: false 86 | 87 | By default, this role will install the latest version of Jenkins using the official repositories according to the platform. You can install the current LTS version instead by setting this to `false`. 88 | 89 | The default repositories (listed below) can be overridden as well. 90 | 91 | # For RedHat/CentOS: 92 | jenkins_repo_url: https://pkg.jenkins.io/redhat{{ '-stable' if (jenkins_prefer_lts | bool) else '' }}/jenkins.repo 93 | jenkins_repo_key_url: https://pkg.jenkins.io/redhat{{ '-stable' if (jenkins_prefer_lts | bool) else '' }}/jenkins.io.key 94 | 95 | # For Debian/Ubuntu: 96 | jenkins_repo_url: deb https://pkg.jenkins.io/debian{{ '-stable' if (jenkins_prefer_lts | bool) else '' }} binary/ 97 | jenkins_repo_key_url: https://pkg.jenkins.io/debian{{ '-stable' if (jenkins_prefer_lts | bool) else '' }}/jenkins.io.key 98 | 99 | It is also possible to prevent the repo file from being added by setting `jenkins_repo_url: ''`. This is useful if, for example, you sign your own packages or run internal package management (e.g. Spacewalk). 100 | 101 | jenkins_java_options: "-Djenkins.install.runSetupWizard=false" 102 | 103 | Extra Java options for the Jenkins launch command configured in the init file can be set with the var `jenkins_java_options`. For example, if you want to configure the timezone Jenkins uses, add `-Dorg.apache.commons.jelly.tags.fmt.timeZone=America/New_York`. By default, the option to disable the Jenkins 2.0 setup wizard is added. 104 | 105 | jenkins_init_changes: 106 | - option: "JENKINS_ARGS" 107 | value: "--prefix={{ jenkins_url_prefix }}" 108 | - option: "JENKINS_JAVA_OPTIONS" 109 | value: "{{ jenkins_java_options }}" 110 | 111 | Changes made to the Jenkins init script; the default set of changes set the configured URL prefix and add in configured Java options for Jenkins' startup. You can add other option/value pairs if you need to set other options for the Jenkins init file. 112 | 113 | jenkins_proxy_host: "" 114 | jenkins_proxy_port: "" 115 | jenkins_proxy_noproxy: 116 | - "127.0.0.1" 117 | - "localhost" 118 | 119 | If you are running Jenkins behind a proxy server, configure these options appropriately. Otherwise Jenkins will be configured with a direct Internet connection. 120 | 121 | ## Dependencies 122 | 123 | None. 124 | 125 | ## Example Playbook 126 | 127 | ```yaml 128 | - hosts: jenkins 129 | become: true 130 | 131 | vars: 132 | jenkins_hostname: jenkins.example.com 133 | java_packages: 134 | - openjdk-8-jdk 135 | 136 | roles: 137 | - role: geerlingguy.java 138 | - role: geerlingguy.jenkins 139 | ``` 140 | 141 | Note that `java_packages` may need different versions depending on your distro (e.g. `openjdk-11-jdk` for Debian 10, or `java-1.8.0-openjdk` for RHEL 7 or 8). 142 | 143 | ## License 144 | 145 | MIT (Expat) / BSD 146 | 147 | ## Author Information 148 | 149 | This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/). 150 | -------------------------------------------------------------------------------- /roles/jenkins_role/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Optional method of pinning a specific version of Jenkins and/or overriding the 3 | # default Jenkins packaging URL. 4 | # jenkins_version: "1.644" 5 | # jenkins_pkg_url: "https://www.example.com" 6 | 7 | # Change this to `latest` to update Jenkins if a newer version is available. 8 | jenkins_package_state: present 9 | 10 | jenkins_prefer_lts: false 11 | 12 | jenkins_connection_delay: 5 13 | jenkins_connection_retries: 60 14 | jenkins_home: /var/lib/jenkins 15 | jenkins_hostname: localhost 16 | jenkins_http_port: 8080 17 | jenkins_jar_location: /opt/jenkins-cli.jar 18 | jenkins_url_prefix: "" 19 | jenkins_java_options: "-Djenkins.install.runSetupWizard=false" 20 | 21 | # Plugin list can use the plugin name, or a name/version dict. 22 | jenkins_plugins: [] 23 | # - blueocean 24 | # - name: influxdb 25 | # version: "1.12.1" 26 | 27 | jenkins_plugins_state: present 28 | jenkins_plugin_updates_expiration: 86400 29 | jenkins_plugin_timeout: 30 30 | jenkins_plugins_install_dependencies: true 31 | jenkins_updates_url: "https://updates.jenkins.io" 32 | 33 | jenkins_admin_username: admin 34 | jenkins_admin_password: admin 35 | jenkins_admin_password_file: "" 36 | 37 | jenkins_process_user: jenkins 38 | jenkins_process_group: "{{ jenkins_process_user }}" 39 | 40 | jenkins_init_changes: 41 | - option: "JENKINS_ARGS" 42 | value: "--prefix={{ jenkins_url_prefix }}" 43 | - option: "{{ jenkins_java_options_env_var }}" 44 | value: "{{ jenkins_java_options }}" 45 | 46 | # If Jenkins is behind a proxy, configure this. 47 | jenkins_proxy_host: "" 48 | jenkins_proxy_port: "" 49 | jenkins_proxy_noproxy: 50 | - "127.0.0.1" 51 | - "localhost" 52 | -------------------------------------------------------------------------------- /roles/jenkins_role/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart jenkins 3 | service: name=jenkins state=restarted 4 | 5 | - name: configure default users 6 | template: 7 | src: basic-security.groovy.j2 8 | dest: "{{ jenkins_home }}/init.groovy.d/basic-security.groovy" 9 | owner: "{{ jenkins_process_user }}" 10 | group: "{{ jenkins_process_group }}" 11 | mode: 0775 12 | register: jenkins_users_config 13 | -------------------------------------------------------------------------------- /roles/jenkins_role/meta/.galaxy_install_info: -------------------------------------------------------------------------------- 1 | {install_date: 'Wed Nov 11 19:33:39 2020', version: 4.3.0} 2 | -------------------------------------------------------------------------------- /roles/jenkins_role/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: [] 3 | 4 | galaxy_info: 5 | author: geerlingguy 6 | description: Jenkins CI 7 | company: "Midwestern Mac, LLC" 8 | license: "license (BSD, MIT)" 9 | min_ansible_version: 2.4 10 | platforms: 11 | - name: EL 12 | versions: 13 | - 6 14 | - 7 15 | - 8 16 | - name: Fedora 17 | versions: 18 | - all 19 | - name: Debian 20 | versions: 21 | - all 22 | - name: Ubuntu 23 | versions: 24 | - all 25 | galaxy_tags: 26 | - development 27 | - packaging 28 | - jenkins 29 | - ci 30 | -------------------------------------------------------------------------------- /roles/jenkins_role/molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | pre_tasks: 7 | - include_tasks: java-8.yml 8 | 9 | - include_tasks: java-11.yml 10 | when: 11 | - ansible_distribution == 'Debian' 12 | - ansible_distribution_major_version == '10' 13 | 14 | roles: 15 | - role: geerlingguy.java 16 | - role: geerlingguy.jenkins 17 | 18 | post_tasks: 19 | - name: Check if Jenkins is running. 20 | uri: 21 | url: "http://127.0.0.1:8080/" 22 | -------------------------------------------------------------------------------- /roles/jenkins_role/molecule/default/java-11.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Set the java_packages variable (Debian). 3 | set_fact: 4 | java_packages: 5 | - openjdk-11-jdk 6 | when: ansible_os_family == 'Debian' 7 | -------------------------------------------------------------------------------- /roles/jenkins_role/molecule/default/java-8.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Debian. 3 | - name: Update apt cache. 4 | apt: update_cache=true cache_valid_time=600 5 | when: ansible_os_family == 'Debian' 6 | changed_when: false 7 | 8 | - name: Set the java_packages variable (Debian). 9 | set_fact: 10 | java_packages: 11 | - openjdk-8-jdk 12 | when: ansible_os_family == 'Debian' 13 | 14 | # Red Hat. 15 | - name: Set the java_packages variable (RedHat). 16 | set_fact: 17 | java_packages: 18 | - java-1.8.0-openjdk 19 | when: ansible_os_family == 'RedHat' 20 | -------------------------------------------------------------------------------- /roles/jenkins_role/molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: docker 6 | lint: | 7 | set -e 8 | yamllint . 9 | ansible-lint 10 | platforms: 11 | - name: instance 12 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest" 13 | command: ${MOLECULE_DOCKER_COMMAND:-""} 14 | volumes: 15 | - /sys/fs/cgroup:/sys/fs/cgroup:ro 16 | privileged: true 17 | pre_build_image: true 18 | provisioner: 19 | name: ansible 20 | playbooks: 21 | converge: ${MOLECULE_PLAYBOOK:-converge.yml} 22 | -------------------------------------------------------------------------------- /roles/jenkins_role/molecule/default/playbook-http-port.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | vars: 7 | jenkins_http_port: 8081 8 | 9 | pre_tasks: 10 | - include_tasks: java-8.yml 11 | 12 | roles: 13 | - geerlingguy.java 14 | - geerlingguy.jenkins 15 | 16 | post_tasks: 17 | - name: Ensure Jenkins is running on the specified port. 18 | uri: 19 | url: "http://127.0.0.1:{{ jenkins_http_port }}" 20 | status_code: 200 21 | register: result 22 | until: result.status == 200 23 | retries: 60 24 | delay: 1 25 | -------------------------------------------------------------------------------- /roles/jenkins_role/molecule/default/playbook-jenkins-version.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | vars: 7 | jenkins_version: "2.220" 8 | 9 | roles: 10 | - geerlingguy.java 11 | - geerlingguy.jenkins 12 | 13 | post_tasks: 14 | - name: Check installed version of Jenkins. 15 | command: rpm -q jenkins 16 | args: 17 | warn: false 18 | changed_when: false 19 | register: jenkins_rpm_version 20 | tags: ['skip_ansible_lint'] 21 | 22 | - name: Print installed Jenkins package information. 23 | debug: var=jenkins_rpm_version 24 | 25 | - name: Fail if version doesn't match what we wanted. 26 | fail: 27 | when: "jenkins_version not in jenkins_rpm_version.stdout" 28 | -------------------------------------------------------------------------------- /roles/jenkins_role/molecule/default/playbook-plugins-with-home.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | vars: 7 | jenkins_plugins: 8 | - ghprb 9 | - greenballs 10 | - {name: cloudbees-folder, version: 6.11} 11 | jenkins_home: /tmp/jenkins 12 | jenkins_plugin_timeout: 120 13 | 14 | pre_tasks: 15 | - include_tasks: java-8.yml 16 | 17 | roles: 18 | - geerlingguy.java 19 | - geerlingguy.jenkins 20 | 21 | post_tasks: 22 | - name: Verify JENKINS_HOME is correct. 23 | stat: 24 | path: "{{ jenkins_home }}/config.xml" 25 | register: jenkins_home_config 26 | 27 | - name: Fail if Jenkins config file doesn't exist. 28 | fail: 29 | when: not jenkins_home_config.stat.exists 30 | 31 | - name: List plugins directory contents. 32 | command: "ls {{ jenkins_home }}/plugins" 33 | register: plugins_contents 34 | changed_when: false 35 | tags: ['skip_ansible_lint'] 36 | 37 | - name: Verify greenballs plugin exists. 38 | stat: 39 | path: "{{ jenkins_home }}/plugins/greenballs.jpi" 40 | register: greenballs_plugin 41 | 42 | - name: Fail if greenballs plugin file doesn't exist. 43 | fail: 44 | when: not greenballs_plugin.stat.exists 45 | 46 | - name: Verify cloudbees-folder plugin exists. 47 | stat: 48 | path: "{{ jenkins_home }}/plugins/cloudbees-folder.jpi" 49 | register: folder_plugin 50 | 51 | - name: Fail if cloudbees-folder plugin file doesn't exist. 52 | fail: 53 | when: not folder_plugin.stat.exists 54 | 55 | - name: Ensure Jenkins is running. 56 | uri: 57 | url: "http://127.0.0.1:8080/" 58 | status_code: 200 59 | register: result 60 | until: result.status == 200 61 | retries: 60 62 | delay: 1 63 | -------------------------------------------------------------------------------- /roles/jenkins_role/molecule/default/playbook-prefix.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | 6 | vars: 7 | jenkins_url_prefix: /jenkins 8 | 9 | pre_tasks: 10 | - include_tasks: java-8.yml 11 | 12 | roles: 13 | - geerlingguy.java 14 | - geerlingguy.jenkins 15 | 16 | post_tasks: 17 | - name: Ensure Jenkins is running with the specified prefix. 18 | uri: 19 | url: "http://127.0.0.1:8080{{ jenkins_url_prefix }}" 20 | status_code: 200 21 | register: result 22 | until: result.status == 200 23 | retries: 60 24 | delay: 1 25 | -------------------------------------------------------------------------------- /roles/jenkins_role/molecule/default/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - src: geerlingguy.java 3 | -------------------------------------------------------------------------------- /roles/jenkins_role/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Variable setup. 3 | - name: Include OS-Specific variables 4 | include_vars: "{{ ansible_os_family }}.yml" 5 | 6 | - name: Define jenkins_repo_url 7 | set_fact: 8 | jenkins_repo_url: "{{ __jenkins_repo_url }}" 9 | when: jenkins_repo_url is not defined 10 | 11 | - name: Define jenkins_repo_key_url 12 | set_fact: 13 | jenkins_repo_key_url: "{{ __jenkins_repo_key_url }}" 14 | when: jenkins_repo_key_url is not defined 15 | 16 | - name: Define jenkins_pkg_url 17 | set_fact: 18 | jenkins_pkg_url: "{{ __jenkins_pkg_url }}" 19 | when: jenkins_pkg_url is not defined 20 | 21 | # Setup/install tasks. 22 | - include_tasks: setup-RedHat.yml 23 | when: ansible_os_family == 'RedHat' 24 | 25 | - include_tasks: setup-Debian.yml 26 | when: ansible_os_family == 'Debian' 27 | 28 | # Configure Jenkins init settings. 29 | - include_tasks: settings.yml 30 | 31 | # Make sure Jenkins starts, then configure Jenkins. 32 | - name: Ensure Jenkins is started and runs on startup. 33 | service: name=jenkins state=started enabled=yes 34 | 35 | - name: Wait for Jenkins to start up before proceeding. 36 | uri: 37 | url: "http://{{ jenkins_hostname }}:{{ jenkins_http_port }}{{ jenkins_url_prefix }}/cli/" 38 | method: GET 39 | return_content: "yes" 40 | timeout: 5 41 | body_format: raw 42 | follow_redirects: "no" 43 | status_code: 200,403 44 | register: result 45 | until: (result.status == 403 or result.status == 200) and (result.content.find("Please wait while") == -1) 46 | retries: "{{ jenkins_connection_retries }}" 47 | delay: "{{ jenkins_connection_delay }}" 48 | changed_when: false 49 | check_mode: false 50 | 51 | - name: Get the jenkins-cli jarfile from the Jenkins server. 52 | get_url: 53 | url: "http://{{ jenkins_hostname }}:{{ jenkins_http_port }}{{ jenkins_url_prefix }}/jnlpJars/jenkins-cli.jar" 54 | dest: "{{ jenkins_jar_location }}" 55 | register: jarfile_get 56 | until: "'OK' in jarfile_get.msg or '304' in jarfile_get.msg or 'file already exists' in jarfile_get.msg" 57 | retries: 5 58 | delay: 10 59 | check_mode: false 60 | 61 | - name: Remove Jenkins security init scripts after first startup. 62 | file: 63 | path: "{{ jenkins_home }}/init.groovy.d/basic-security.groovy" 64 | state: absent 65 | 66 | # Update Jenkins and install configured plugins. 67 | - include_tasks: plugins.yml 68 | -------------------------------------------------------------------------------- /roles/jenkins_role/tasks/plugins.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # jenkins_plugin module doesn't support password files. 3 | - name: Get Jenkins admin password from file. 4 | slurp: 5 | src: "{{ jenkins_admin_password_file }}" 6 | register: adminpasswordfile 7 | no_log: true 8 | when: jenkins_admin_password_file | default(false) 9 | tags: ['skip_ansible_lint'] 10 | 11 | - name: Set Jenkins admin password fact. 12 | set_fact: 13 | jenkins_admin_password: "{{ adminpasswordfile['stdout'] | default(jenkins_admin_password) }}" 14 | no_log: true 15 | 16 | # Update Jenkins so that plugin updates don't fail. 17 | - name: Create Jenkins updates directory. 18 | file: 19 | path: "{{ jenkins_home }}/updates" 20 | state: directory 21 | owner: jenkins 22 | group: jenkins 23 | 24 | - name: Download current plugin updates from Jenkins update site. 25 | get_url: 26 | url: "{{ jenkins_updates_url }}/update-center.json" 27 | dest: "{{ jenkins_home }}/updates/default.json" 28 | owner: jenkins 29 | group: jenkins 30 | mode: 0440 31 | changed_when: false 32 | register: get_result 33 | until: get_result is success 34 | retries: 3 35 | delay: 2 36 | 37 | - name: Remove first and last line from json file. 38 | replace: 39 | path: "{{ jenkins_home }}/updates/default.json" 40 | regexp: "1d;$d" 41 | 42 | - name: Install Jenkins plugins using password. 43 | jenkins_plugin: 44 | name: "{{ item.name | default(item) }}" 45 | version: "{{ item.version | default(omit) }}" 46 | jenkins_home: "{{ jenkins_home }}" 47 | url_username: "{{ jenkins_admin_username }}" 48 | url_password: "{{ jenkins_admin_password }}" 49 | state: "{{ 'present' if item.version is defined else jenkins_plugins_state }}" 50 | timeout: "{{ jenkins_plugin_timeout }}" 51 | updates_expiration: "{{ jenkins_plugin_updates_expiration }}" 52 | updates_url: "{{ jenkins_updates_url }}" 53 | url: "http://{{ jenkins_hostname }}:{{ jenkins_http_port }}{{ jenkins_url_prefix }}" 54 | with_dependencies: "{{ jenkins_plugins_install_dependencies }}" 55 | with_items: "{{ jenkins_plugins }}" 56 | when: jenkins_admin_password | default(false) 57 | notify: restart jenkins 58 | tags: ['skip_ansible_lint'] 59 | register: plugin_result 60 | until: plugin_result is success 61 | retries: 3 62 | delay: 2 63 | -------------------------------------------------------------------------------- /roles/jenkins_role/tasks/settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check if jenkins_init_file exists. 3 | stat: 4 | path: "{{ jenkins_init_file }}" 5 | register: jenkins_init_file_stat 6 | 7 | - name: Ensure jenkins_init_file exists. 8 | file: 9 | path: "{{ jenkins_init_file }}" 10 | state: touch 11 | when: not jenkins_init_file_stat.stat.exists 12 | 13 | - name: Modify variables in init file. 14 | lineinfile: 15 | dest: "{{ jenkins_init_file }}" 16 | insertafter: '^{{ item.option }}=' 17 | regexp: '^{{ item.option }}=\"\${{ item.option }} ' 18 | line: '{{ item.option }}="${{ item.option }} {{ item.value }}"' 19 | state: present 20 | with_items: "{{ jenkins_init_changes }}" 21 | register: jenkins_init_prefix 22 | 23 | - name: Ensure jenkins_home {{ jenkins_home }} exists. 24 | file: 25 | path: "{{ jenkins_home }}" 26 | state: directory 27 | owner: jenkins 28 | group: jenkins 29 | mode: u+rwx 30 | follow: true 31 | 32 | - name: Set the Jenkins home directory. 33 | lineinfile: 34 | dest: "{{ jenkins_init_file }}" 35 | regexp: '^JENKINS_HOME=.*' 36 | line: 'JENKINS_HOME={{ jenkins_home }}' 37 | register: jenkins_home_config 38 | 39 | - name: Immediately restart Jenkins on init config changes. 40 | service: name=jenkins state=restarted 41 | when: jenkins_init_prefix.changed 42 | tags: ['skip_ansible_lint'] 43 | 44 | - name: Set HTTP port in Jenkins config. 45 | lineinfile: 46 | backrefs: true 47 | dest: "{{ jenkins_init_file }}" 48 | regexp: '^{{ jenkins_http_port_param }}=' 49 | line: '{{ jenkins_http_port_param }}={{ jenkins_http_port }}' 50 | register: jenkins_http_config 51 | 52 | - name: Create custom init scripts directory. 53 | file: 54 | path: "{{ jenkins_home }}/init.groovy.d" 55 | state: directory 56 | owner: "{{ jenkins_process_user }}" 57 | group: "{{ jenkins_process_group }}" 58 | mode: 0775 59 | 60 | - name: Configure proxy config for Jenkins 61 | template: 62 | src: proxy.xml 63 | dest: "{{ jenkins_home }}/proxy.xml" 64 | owner: "{{ jenkins_process_user }}" 65 | group: "{{ jenkins_process_group }}" 66 | mode: 0664 67 | register: jenkins_proxy_config 68 | when: 69 | - jenkins_proxy_host | length > 0 70 | - jenkins_proxy_port | length > 0 71 | 72 | - name: Trigger handlers immediately in case Jenkins was installed 73 | meta: flush_handlers 74 | 75 | - name: Immediately restart Jenkins on http or user changes. 76 | service: name=jenkins state=restarted 77 | when: > 78 | (jenkins_users_config is defined and jenkins_users_config.changed) 79 | or (jenkins_http_config is defined and jenkins_http_config.changed) 80 | or (jenkins_home_config is defined and jenkins_home_config.changed) 81 | or (jenkins_proxy_config is defined and jenkins_proxy_config.changed) 82 | tags: ['skip_ansible_lint'] 83 | -------------------------------------------------------------------------------- /roles/jenkins_role/tasks/setup-Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure dependencies are installed. 3 | apt: 4 | name: 5 | - curl 6 | - apt-transport-https 7 | - gnupg 8 | state: present 9 | 10 | - name: Add Jenkins apt repository key. 11 | apt_key: 12 | url: "{{ jenkins_repo_key_url }}" 13 | state: present 14 | 15 | - name: Add Jenkins apt repository. 16 | apt_repository: 17 | repo: "{{ jenkins_repo_url }}" 18 | state: present 19 | update_cache: true 20 | when: jenkins_repo_url | default(false) 21 | tags: ['skip_ansible_lint'] 22 | 23 | - name: Download specific Jenkins version. 24 | get_url: 25 | url: "{{ jenkins_pkg_url }}/jenkins_{{ jenkins_version }}_all.deb" 26 | dest: "/tmp/jenkins_{{ jenkins_version }}_all.deb" 27 | when: jenkins_version is defined 28 | 29 | - name: Check if we downloaded a specific version of Jenkins. 30 | stat: 31 | path: "/tmp/jenkins_{{ jenkins_version }}_all.deb" 32 | register: specific_version 33 | when: jenkins_version is defined 34 | 35 | - name: Install our specific version of Jenkins. 36 | apt: 37 | deb: "/tmp/jenkins_{{ jenkins_version }}_all.deb" 38 | state: present 39 | when: jenkins_version is defined and specific_version.stat.exists 40 | notify: configure default users 41 | 42 | - name: Ensure Jenkins is installed. 43 | apt: 44 | name: jenkins 45 | state: "{{ jenkins_package_state }}" 46 | notify: configure default users 47 | -------------------------------------------------------------------------------- /roles/jenkins_role/tasks/setup-RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Ensure dependencies are installed. 3 | package: 4 | name: 5 | - curl 6 | - initscripts 7 | - "{{ 'libselinux-python' if ansible_python['version']['major'] < 3 else 'python3-libselinux' }}" 8 | state: present 9 | 10 | - name: Ensure Jenkins repo is installed. 11 | get_url: 12 | url: "{{ jenkins_repo_url }}" 13 | dest: /etc/yum.repos.d/jenkins.repo 14 | when: jenkins_repo_url | default(false) 15 | 16 | - name: Add Jenkins repo GPG key. 17 | rpm_key: 18 | state: present 19 | key: "{{ jenkins_repo_key_url }}" 20 | when: jenkins_repo_url | default(false) 21 | 22 | - name: Download specific Jenkins version. 23 | get_url: 24 | url: "{{ jenkins_pkg_url }}/jenkins-{{ jenkins_version }}-1.1.noarch.rpm" 25 | dest: "/tmp/jenkins-{{ jenkins_version }}-1.1.noarch.rpm" 26 | when: jenkins_version is defined 27 | 28 | - name: Check if we downloaded a specific version of Jenkins. 29 | stat: 30 | path: "/tmp/jenkins-{{ jenkins_version }}-1.1.noarch.rpm" 31 | register: specific_version 32 | when: jenkins_version is defined 33 | 34 | - name: Install our specific version of Jenkins. 35 | package: 36 | name: "/tmp/jenkins-{{ jenkins_version }}-1.1.noarch.rpm" 37 | state: present 38 | when: jenkins_version is defined and specific_version.stat.exists 39 | notify: configure default users 40 | 41 | - name: Ensure Jenkins is installed. 42 | package: 43 | name: jenkins 44 | state: "{{ jenkins_package_state }}" 45 | notify: configure default users 46 | -------------------------------------------------------------------------------- /roles/jenkins_role/templates/basic-security.groovy.j2: -------------------------------------------------------------------------------- 1 | #!groovy 2 | import hudson.security.* 3 | import jenkins.model.* 4 | 5 | def instance = Jenkins.getInstance() 6 | def hudsonRealm = new HudsonPrivateSecurityRealm(false) 7 | def users = hudsonRealm.getAllUsers() 8 | users_s = users.collect { it.toString() } 9 | 10 | // Create the admin user account if it doesn't already exist. 11 | if ("{{ jenkins_admin_username }}" in users_s) { 12 | println "Admin user already exists - updating password" 13 | 14 | def user = hudson.model.User.get('{{ jenkins_admin_username }}'); 15 | def password = hudson.security.HudsonPrivateSecurityRealm.Details.fromPlainPassword('{{ jenkins_admin_password }}') 16 | user.addProperty(password) 17 | user.save() 18 | } 19 | else { 20 | println "--> creating local admin user" 21 | 22 | hudsonRealm.createAccount('{{ jenkins_admin_username }}', '{{ jenkins_admin_password }}') 23 | instance.setSecurityRealm(hudsonRealm) 24 | 25 | def strategy = new FullControlOnceLoggedInAuthorizationStrategy() 26 | instance.setAuthorizationStrategy(strategy) 27 | instance.save() 28 | } 29 | -------------------------------------------------------------------------------- /roles/jenkins_role/templates/proxy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ jenkins_proxy_host }} 4 | {{ jenkins_proxy_port}} 5 | {{ jenkins_proxy_noproxy | join(',') }} 6 | 7 | -------------------------------------------------------------------------------- /roles/jenkins_role/tests/test-plugins.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kabary/rhce9/6c4f998b488fb8dbb3a3acac566de10309a07cef/roles/jenkins_role/tests/test-plugins.yml -------------------------------------------------------------------------------- /roles/jenkins_role/vars/Debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __jenkins_repo_url: deb https://pkg.jenkins.io/debian{{ '-stable' if (jenkins_prefer_lts | bool) else '' }} binary/ 3 | __jenkins_repo_key_url: https://pkg.jenkins.io/debian{{ '-stable' if (jenkins_prefer_lts | bool) else '' }}/jenkins.io.key 4 | __jenkins_pkg_url: https://pkg.jenkins.io/debian/binary 5 | jenkins_init_file: /etc/default/jenkins 6 | jenkins_http_port_param: HTTP_PORT 7 | jenkins_java_options_env_var: JAVA_ARGS 8 | -------------------------------------------------------------------------------- /roles/jenkins_role/vars/RedHat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | __jenkins_repo_url: https://pkg.jenkins.io/redhat{{ '-stable' if (jenkins_prefer_lts | bool) else '' }}/jenkins.repo 3 | __jenkins_repo_key_url: https://pkg.jenkins.io/redhat{{ '-stable' if (jenkins_prefer_lts | bool) else '' }}/jenkins.io.key 4 | __jenkins_pkg_url: https://pkg.jenkins.io/redhat 5 | jenkins_init_file: /etc/sysconfig/jenkins 6 | jenkins_http_port_param: JENKINS_PORT 7 | jenkins_java_options_env_var: JENKINS_JAVA_OPTIONS 8 | -------------------------------------------------------------------------------- /roles/myrole/tasks/main.yml: -------------------------------------------------------------------------------- 1 | - name: 2 | debug: 3 | msg: "I am the first task in myrole." 4 | 5 | - name: 6 | debug: 7 | msg: "I am the second task in myrole." 8 | -------------------------------------------------------------------------------- /roles/nginx_role/README.md: -------------------------------------------------------------------------------- 1 | nginx 2 | ===== 3 | 4 | This role installs and configures the nginx web server. The user can specify 5 | any http configuration parameters they wish to apply their site. Any number of 6 | sites can be added with configurations of your choice. 7 | 8 | Requirements 9 | ------------ 10 | 11 | This role requires Ansible 1.4 or higher and platform requirements are listed 12 | in the metadata file. 13 | 14 | Role Variables 15 | -------------- 16 | 17 | The variables that can be passed to this role and a brief description about 18 | them are as follows. 19 | 20 | # The max clients allowed 21 | nginx_max_clients: 512 22 | 23 | # A hash of the http paramters. Note that any 24 | # valid nginx http paramters can be added here. 25 | # (see the nginx documentation for details.) 26 | nginx_http_params: 27 | sendfile: "on" 28 | tcp_nopush: "on" 29 | tcp_nodelay: "on" 30 | keepalive_timeout: "65" 31 | access_log: "/var/log/nginx/access.log" 32 | error_log: "/var/log/nginx/error.log" 33 | 34 | # A list of hashs that define the servers for nginx, 35 | # as with http parameters. Any valid server parameters 36 | # can be defined here. 37 | nginx_sites: 38 | - server: 39 | file_name: foo 40 | listen: 8080 41 | server_name: localhost 42 | root: "/tmp/site1" 43 | location1: {name: /, try_files: "$uri $uri/ /index.html"} 44 | location2: {name: /images/, try_files: "$uri $uri/ /index.html"} 45 | - server: 46 | file_name: bar 47 | listen: 9090 48 | server_name: ansible 49 | root: "/tmp/site2" 50 | location1: {name: /, try_files: "$uri $uri/ /index.html"} 51 | location2: {name: /images/, try_files: "$uri $uri/ /index.html"} 52 | 53 | Examples 54 | ======== 55 | 56 | 1) Install nginx with HTTP directives of choices, but with no sites 57 | configured: 58 | 59 | - hosts: all 60 | roles: 61 | - {role: nginx, 62 | nginx_http_params: { sendfile: "on", 63 | access_log: "/var/log/nginx/access.log"}, 64 | nginx_sites: none } 65 | 66 | 67 | 2) Install nginx with different HTTP directives than previous example, but no 68 | sites configured. 69 | 70 | - hosts: all 71 | roles: 72 | - {role: nginx, 73 | nginx_http_params: { tcp_nodelay: "on", 74 | error_log: "/var/log/nginx/error.log"}, 75 | nginx_sites: none } 76 | 77 | Note: Please make sure the HTTP directives passed are valid, as this role 78 | won't check for the validity of the directives. See the nginx documentation 79 | for details. 80 | 81 | 3) Install nginx and add a site to the configuration. 82 | 83 | - hosts: all 84 | 85 | roles: 86 | - role: nginx, 87 | nginx_http_params: 88 | sendfile: "on" 89 | access_log: "/var/log/nginx/access.log" 90 | nginx_sites: 91 | - server: 92 | file_name: bar 93 | listen: 8080 94 | location1: {name: "/", try_files: "$uri $uri/ /index.html"} 95 | location2: {name: /images/, try_files: "$uri $uri/ /index.html"} 96 | 97 | Note: Each site added is represented by list of hashes, and the configurations 98 | generated are populated in `/etc/nginx/sites-available/` and have corresponding 99 | symlinks from `/etc/nginx/sites-enabled/` 100 | 101 | The file name for the specific site configurtaion is specified in the hash 102 | with the key "file_name", any valid server directives can be added to hash. 103 | For location directive add the key "location" suffixed by a unique number, the 104 | value for the location is hash, please make sure they are valid location 105 | directives. 106 | 107 | 4) Install Nginx and add 2 sites (different method) 108 | 109 | --- 110 | - hosts: all 111 | roles: 112 | - role: nginx 113 | nginx_http_params: 114 | sendfile: "on" 115 | access_log: "/var/log/nginx/access.log" 116 | nginx_sites: 117 | - server: 118 | file_name: foo 119 | listen: 8080 120 | server_name: localhost 121 | root: "/tmp/site1" 122 | location1: {name: /, try_files: "$uri $uri/ /index.html"} 123 | location2: {name: /images/, try_files: "$uri $uri/ /index.html"} 124 | - server: 125 | file_name: bar 126 | listen: 9090 127 | server_name: ansible 128 | root: "/tmp/site2" 129 | location1: {name: /, try_files: "$uri $uri/ /index.html"} 130 | location2: {name: /images/, try_files: "$uri $uri/ /index.html"} 131 | 132 | Dependencies 133 | ------------ 134 | 135 | None 136 | 137 | License 138 | ------- 139 | 140 | BSD 141 | 142 | Author Information 143 | ------------------ 144 | 145 | Benno Joy 146 | 147 | 148 | -------------------------------------------------------------------------------- /roles/nginx_role/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | nginx_max_clients: 512 4 | 5 | nginx_http_params: 6 | sendfile: "on" 7 | tcp_nopush: "on" 8 | tcp_nodelay: "on" 9 | keepalive_timeout: "65" 10 | 11 | nginx_log_dir: "/var/log/nginx" 12 | nginx_access_log_name: "access.log" 13 | nginx_error_log_name: "error.log" 14 | nginx_separate_logs_per_site: False 15 | 16 | nginx_sites: 17 | - server: 18 | file_name: foo 19 | listen: 8080 20 | server_name: localhost 21 | root: "/tmp/site1" 22 | location1: {name: /, try_files: "$uri $uri/ /index.html"} 23 | location2: {name: /images/, try_files: "$uri $uri/ /index.html"} 24 | - server: 25 | file_name: bar 26 | listen: 9090 27 | server_name: ansible 28 | root: "/tmp/site2" 29 | location1: {name: /, try_files: "$uri $uri/ /index.html"} 30 | location2: {name: /images/, try_files: "$uri $uri/ /index.html"} 31 | -------------------------------------------------------------------------------- /roles/nginx_role/files/epel.repo: -------------------------------------------------------------------------------- 1 | [epel] 2 | name=Extra Packages for Enterprise Linux 6 - $basearch 3 | baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch 4 | #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch 5 | failovermethod=priority 6 | enabled=1 7 | gpgcheck=0 8 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 9 | 10 | [epel-debuginfo] 11 | name=Extra Packages for Enterprise Linux 6 - $basearch - Debug 12 | #baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug 13 | mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch 14 | failovermethod=priority 15 | enabled=0 16 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 17 | gpgcheck=1 18 | 19 | [epel-source] 20 | name=Extra Packages for Enterprise Linux 6 - $basearch - Source 21 | #baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS 22 | mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch 23 | failovermethod=priority 24 | enabled=0 25 | gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 26 | gpgcheck=1 27 | -------------------------------------------------------------------------------- /roles/nginx_role/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart nginx 3 | service: name=nginx state=restarted 4 | 5 | - name: reload nginx 6 | service: name=nginx state=reloaded 7 | -------------------------------------------------------------------------------- /roles/nginx_role/meta/.galaxy_install_info: -------------------------------------------------------------------------------- 1 | {install_date: 'Wed Nov 11 19:33:38 2020', version: master} 2 | -------------------------------------------------------------------------------- /roles/nginx_role/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: "Benno Joy" 4 | company: AnsibleWorks 5 | license: BSD 6 | min_ansible_version: 1.4 7 | platforms: 8 | - name: EL 9 | versions: 10 | - 5 11 | - 6 12 | - name: Fedora 13 | versions: 14 | - 16 15 | - 17 16 | - 18 17 | - name: Ubuntu 18 | versions: 19 | - precise 20 | - quantal 21 | - raring 22 | - saucy 23 | categories: 24 | - web 25 | dependencies: [] 26 | 27 | -------------------------------------------------------------------------------- /roles/nginx_role/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Install the selinux python module 4 | yum: name=libselinux-python state=present 5 | when: ansible_os_family == "RedHat" 6 | 7 | - name: Copy the epel packages 8 | copy: src=epel.repo dest=/etc/yum.repos.d/epel_ansible.repo 9 | when: ansible_os_family == "RedHat" 10 | 11 | - name: Install the nginx packages 12 | yum: name={{ item }} state=present 13 | with_items: redhat_pkg 14 | when: ansible_os_family == "RedHat" 15 | 16 | - name: Install the nginx packages 17 | apt: name={{ item }} state=present update_cache=yes 18 | with_items: ubuntu_pkg 19 | environment: env 20 | when: ansible_os_family == "Debian" 21 | 22 | - name: Create the directories for site specific configurations 23 | file: path=/etc/nginx/{{ item }} state=directory owner=root group=root mode=0755 24 | with_items: 25 | - "sites-available" 26 | - "sites-enabled" 27 | 28 | - name: Copy the nginx configuration file 29 | template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf 30 | notify: 31 | - restart nginx 32 | 33 | - name: Copy the nginx default configuration file 34 | template: src=default.conf.j2 dest=/etc/nginx/conf.d/default.conf 35 | 36 | - name: Copy the nginx default site configuration file 37 | template: src=default.j2 dest=/etc/nginx/sites-available/default 38 | 39 | - name: Create the link for site enabled specific configurations 40 | file: path=/etc/nginx/sites-enabled/default state=link src=/etc/nginx/sites-available/default 41 | 42 | - name: Create the configurations for sites 43 | template: src=site.j2 dest=/etc/nginx/sites-available/{{ item['server']['file_name'] }} 44 | with_items: nginx_sites 45 | when: nginx_sites|lower != 'none' 46 | 47 | - name: Create the links to enable site configurations 48 | file: path=/etc/nginx/sites-enabled/{{ item['server']['file_name'] }} state=link src=/etc/nginx/sites-available/{{ item['server']['file_name'] }} 49 | with_items: nginx_sites 50 | when: nginx_sites|lower != 'none' 51 | notify: 52 | - reload nginx 53 | 54 | - name: start the nginx service 55 | service: name=nginx state=started enabled=yes 56 | 57 | -------------------------------------------------------------------------------- /roles/nginx_role/templates/default.conf.j2: -------------------------------------------------------------------------------- 1 | #{{ ansible_managed }} 2 | -------------------------------------------------------------------------------- /roles/nginx_role/templates/default.j2: -------------------------------------------------------------------------------- 1 | #{{ ansible_managed }} 2 | -------------------------------------------------------------------------------- /roles/nginx_role/templates/nginx.conf.j2: -------------------------------------------------------------------------------- 1 | #{{ ansible_managed }} 2 | {% if ansible_os_family == 'RedHat' %} 3 | user nginx; 4 | {% endif %} 5 | {% if ansible_os_family == 'Debian' %} 6 | user www-data; 7 | {% endif %} 8 | 9 | worker_processes {{ ansible_processor_count }}; 10 | pid /var/run/nginx.pid; 11 | 12 | 13 | events { 14 | worker_connections {{ nginx_max_clients }}; 15 | } 16 | 17 | 18 | http { 19 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 20 | include /etc/nginx/mime.types; 21 | default_type application/octet-stream; 22 | 23 | access_log {{ nginx_log_dir}}/{{ nginx_access_log_name}}; 24 | error_log {{ nginx_log_dir}}/{{ nginx_error_log_name}}; 25 | 26 | {% for k,v in nginx_http_params.iteritems() %} 27 | {{ k }} {{ v }}; 28 | {% endfor %} 29 | 30 | gzip on; 31 | gzip_disable "msie6"; 32 | 33 | include /etc/nginx/conf.d/*.conf; 34 | include /etc/nginx/sites-enabled/*; 35 | } 36 | -------------------------------------------------------------------------------- /roles/nginx_role/templates/site.j2: -------------------------------------------------------------------------------- 1 | server { 2 | 3 | {% if nginx_separate_logs_per_site == True %} 4 | access_log {{ nginx_log_dir}}/{{ item.server.server_name}}-{{ nginx_access_log_name}}; 5 | error_log {{ nginx_log_dir}}/{{ item.server.server_name}}-{{ nginx_error_log_name}}; 6 | {% endif %} 7 | 8 | {% for k,v in item.server.iteritems() %} 9 | {% if k.find('location') == -1 and k != 'file_name' %} 10 | {{ k }} {{ v }}; 11 | {% endif %} 12 | {% endfor %} 13 | 14 | {% for k,v in item.server.iteritems() if k.find('location') != -1 %} 15 | location {{ v.name }} { 16 | {% for x,y in v.iteritems() if x != 'name' %} 17 | {{ x }} {{ y }}; 18 | {% endfor %} 19 | } 20 | {% endfor %} 21 | } 22 | 23 | -------------------------------------------------------------------------------- /roles/nginx_role/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | env: 4 | RUNLEVEL: 1 5 | 6 | redhat_pkg: 7 | - nginx 8 | 9 | ubuntu_pkg: 10 | - python-selinux 11 | - nginx 12 | 13 | 14 | -------------------------------------------------------------------------------- /secret-vault.txt: -------------------------------------------------------------------------------- 1 | L!n*Xh#N%b,Ook 2 | -------------------------------------------------------------------------------- /secret.txt: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 63343431653566633764323561326535323537313339663462616530323536333336343938393063 3 | 6564623639353135363731366164333261343064303634380a323036336136353063303936333131 4 | 31366335636531343139613639356266313233303262393936333135393163663866643735633363 5 | 6133363336663530350a396334303534643731643664313030613565633365346266326539316366 6 | 39636237373932626435656331386130316236356635326430366163613437666161316334626633 7 | 6131633038326232383265663066616239303837663066616361 8 | -------------------------------------------------------------------------------- /secret2.txt: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 65633366376532393463366537356434393132363663303738376335326461383936613065313232 3 | 3866346634663730663064353633363663616634343134370a393539626234646438303031386563 4 | 33636634626430616531386231303931373038373638386337633032646561306261386335373563 5 | 3237336236343436370a623032363236636435646237356232366161356333663038313035333363 6 | 64343165353330313163653030636138303261323961323930346661366363376361376262333665 7 | 6438663334623034383964393430343239356230336463356631 8 | -------------------------------------------------------------------------------- /selinux-status.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Check SELinux Status 3 | hosts: all 4 | tasks: 5 | - name: Display SELinux Status 6 | debug: 7 | msg: "{{ ansible_facts['selinux']['status'] }}" 8 | 9 | - name: Create selinux.out using Jinja2 10 | template: 11 | src: selinux.j2 12 | dest: /tmp/selinux.out 13 | -------------------------------------------------------------------------------- /server-info.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Server Information Summary 3 | hosts: all 4 | tasks: 5 | - name: Create server-info.txt using Jinja2 6 | template: 7 | src: info.j2 8 | dest: /tmp/server-info.txt 9 | -------------------------------------------------------------------------------- /show-facts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: show some facts 3 | hosts: node1 4 | tasks: 5 | - name: display node1 ipv4 address 6 | debug: 7 | msg: IPv4 address is {{ ansible_facts['default_ipv4'].address }} 8 | 9 | - name: display node1 fqdn 10 | debug: 11 | msg: FQDN is {{ ansible_facts['fqdn'] }} 12 | 13 | - name: display node1 OS distribution 14 | debug: 15 | msg: OS Distro is {{ ansible_facts.distribution }} 16 | -------------------------------------------------------------------------------- /templates/hosts.j2: -------------------------------------------------------------------------------- 1 | {% for host in groups['all'] %} 2 | {{ hostvars[host].ansible_facts.default_ipv4.address }} {{ hostvars[host].ansible_facts.fqdn }} {{ hostvars[host].ansible_facts.hostname }} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /templates/index.j2: -------------------------------------------------------------------------------- 1 | A message from {{ inventory_hostname }} 2 | {{ webserver_message }} 3 | -------------------------------------------------------------------------------- /templates/info.j2: -------------------------------------------------------------------------------- 1 | Server Information Summary 2 | -------------------------- 3 | 4 | hostname={{ ansible_facts['hostname'] }} 5 | fqdn={{ ansible_facts['fqdn'] }} 6 | ipaddr={{ ansible_facts['default_ipv4']['address'] }} 7 | distro={{ ansible_facts['distribution'] }} 8 | distro_version={{ ansible_facts['distribution_version'] }} 9 | nameservers={{ ansible_facts['dns']['nameservers'] }} 10 | totalmem={{ ansible_facts['memtotal_mb'] }} 11 | freemem={{ ansible_facts['memfree_mb'] }} 12 | -------------------------------------------------------------------------------- /templates/range.j2: -------------------------------------------------------------------------------- 1 | {% for i in range(1,11) %} 2 | Number {{ i }} 3 | {% endfor %} 4 | -------------------------------------------------------------------------------- /templates/selinux.j2: -------------------------------------------------------------------------------- 1 | {% set selinux_status = ansible_facts['selinux']['status'] %} 2 | 3 | {% if selinux_status == "enabled" %} 4 | "SELINUX IS ENABLED" 5 | {% elif selinux_status == "disabled" %} 6 | "SELINUX IS DISABLED" 7 | {% else %} 8 | "SELINUX IS NOT AVAILABLE" 9 | {% endif %} 10 | -------------------------------------------------------------------------------- /ubuntu-servers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simple Example for using when 3 | hosts: all 4 | tasks: 5 | - name: Detect Ubuntu Servers 6 | debug: 7 | msg: "This is an Ubuntu Server." 8 | when: ansible_facts['distribution'] == "Ubuntu" 9 | -------------------------------------------------------------------------------- /variable-precedence.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Understanding Variable Precedence 3 | hosts: node1 4 | vars: 5 | fav_distro: "Ubuntu" 6 | tasks: 7 | - name: Show value of fav_distro 8 | debug: 9 | msg: Favorite distro is {{ fav_distro }} 10 | -------------------------------------------------------------------------------- /variables-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Working with variables 3 | hosts: node1 4 | tasks: 5 | - name: Load the variables 6 | include_vars: myvars.yml 7 | 8 | - name: Show 2nd item in port_nums 9 | debug: 10 | msg: SSH port is {{ port_nums[1] }} 11 | -------------------------------------------------------------------------------- /vars1.yml: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 62313339383533383232323836386433346535373034623839326332656633303030366664333763 3 | 3730323563303434376361303938346239333730626235330a316464396636383166336534653431 4 | 39303864643739313137326137646331663463666161383931613437383263373935346665396665 5 | 3062386564303662660a316263383961646466323038336665636134306637373033353233616636 6 | 61383164633434383462626464396364323833323939333833323862363864643835 7 | -------------------------------------------------------------------------------- /vars2.yml: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 33383134333538373966623263303334316435636361646539356362356235333765653130373832 3 | 3233343338343030343964333132643961393763366464370a353263343930303537396564333034 4 | 66666531326362313936333063373536393937363166653738333262643034366165333336626239 5 | 3666623361613662630a636365663161346433376231613164333038626435646235393430623335 6 | 36366339376131353632666136613332306164363761316132396330623034646165 7 | -------------------------------------------------------------------------------- /vault-pass.txt: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /vault-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Accessing Vaults in Playbooks 3 | hosts: node2 4 | vars_files: 5 | - web-secrets.yml 6 | - db-secrets.yml 7 | tasks: 8 | - name: Show secret1 value 9 | debug: 10 | msg: "{{ secret1 }}" 11 | 12 | - name: Show secret2 value 13 | debug: 14 | msg: "{{ secret2 }}" 15 | -------------------------------------------------------------------------------- /web-secrets.yml: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 64353462363666366266313464613261666534313364326532316436616332326135363764313731 3 | 6265653061613238336339333862316165333839623861390a616563316665376536306131383631 4 | 34663431383037343935643961393537303665646430633931656661393930663739313635363065 5 | 3432613635323639380a393137306663336534633037383966666234613763626436333362643566 6 | 31373930376639333630313236393532373964346437663962366636643336303464 7 | --------------------------------------------------------------------------------