├── Chapter 10 ├── aws.yaml ├── azure.yaml ├── container.yml ├── gce.yaml ├── k8s-ns-show.yaml ├── k8s-ns.yaml ├── k8s-svc.yaml ├── openstack.yaml ├── rax.yaml └── start-docker-container.yaml ├── Chapter 11 ├── check-mode.yaml ├── debug.yaml ├── debug2.yaml ├── helloworld.yaml ├── inventory ├── print_facts.yaml ├── printvar.yaml ├── remote.yaml ├── syntaxcheck-fixed.yaml └── syntaxcheck.yaml ├── Chapter 2 ├── appservers-emea.yml ├── employee-all-playbook.yml ├── employee-flow-playbook.yml ├── employee-playbook.yml ├── employees-all.yml ├── employees-flow.yml ├── employees.yml ├── frontends-na.yml ├── hosts ├── jinja2-filtering1.yml ├── jinja2-filtering2.yml ├── jinja2-filtering3.yml ├── multiple-document-strings.yaml ├── production-inventory ├── redis-playbook.yml ├── site.yml └── update-apache-version.yml ├── Chapter 3 ├── groupvars1-hostgroups-ini ├── hostgroups-children-ini ├── hostgroups-children-vars-ini ├── hostgroups-ini ├── hostgroups-yml ├── hosts ├── hostvars1-hostgroups-ini ├── hostvars2-hostgroups-ini ├── hostvars2-hostgroups-yml ├── my_inventory ├── my_inventory.yaml ├── site.yml ├── static-groups-mix-ini ├── vartree │ ├── group_vars │ │ └── frontends.yml │ ├── host_vars │ │ └── frt01.example.com.yml │ └── inventory └── vartree2 │ ├── group_vars │ └── frontends │ │ ├── https_port.yml │ │ └── lb_vip.yml │ ├── host_vars │ └── frt01.example.com │ │ └── main.yml │ └── inventory ├── Chapter 4 ├── blocks-error.yml ├── blocks.yml ├── condition.yml ├── condition2.yml ├── condition3.yml ├── debug.yml ├── handlers1.yml ├── handlers2.yml ├── hosts ├── installapache.yml ├── loop1.yml ├── loop2.yml ├── loop3.yml ├── loopmain.yml ├── loopsubtask.yml ├── myplaybook.yaml ├── playandtask.yml ├── playbookvsadhoc.yml ├── role-example1 │ ├── hosts │ ├── roles │ │ └── installapache │ │ │ └── tasks │ │ │ ├── centos.yml │ │ │ ├── main.yml │ │ │ └── ubuntu.yml │ └── site.yml ├── role-example2 │ ├── hosts │ ├── roles │ │ ├── linuxtype │ │ │ └── meta │ │ │ │ └── main.yml │ │ ├── network │ │ │ ├── meta │ │ │ │ └── main.yml │ │ │ └── tasks │ │ │ │ └── main.yml │ │ ├── platform │ │ │ └── meta │ │ │ │ └── main.yml │ │ ├── testrole │ │ │ ├── .travis.yml │ │ │ ├── README.md │ │ │ ├── defaults │ │ │ │ └── main.yml │ │ │ ├── handlers │ │ │ │ └── main.yml │ │ │ ├── meta │ │ │ │ └── main.yml │ │ │ ├── tasks │ │ │ │ └── main.yml │ │ │ ├── tests │ │ │ │ ├── inventory │ │ │ │ └── test.yml │ │ │ └── vars │ │ │ │ └── main.yml │ │ └── version │ │ │ ├── meta │ │ │ └── main.yml │ │ │ └── tasks │ │ │ └── main.yml │ └── site.yml ├── staticvsdynamicroles.yml ├── template.j2 └── templates │ └── src.j2 ├── Chapter 5 ├── args.json ├── better_remote_filecopy.py ├── hosts ├── remote_filecopy.py ├── retval.yml └── testplaybook │ ├── hosts │ ├── library │ └── remote_filecopy.py │ └── testplaybook.yml ├── Chapter 6 ├── filter_plugins │ ├── custom_filter.py │ └── custom_filter.pyc ├── hosts ├── lookup_plugins │ ├── firstchar.py │ └── firstchar.pyc ├── myplugin.yml ├── myplugin2.yml ├── pipetest.yml └── testdoc.txt ├── Chapter 7 ├── best-practise-directory-structure │ ├── filter_plugins │ │ ├── custom_filter.py │ │ └── custom_filter.pyc │ ├── inventories │ │ ├── development │ │ │ ├── group_vars │ │ │ │ └── app.yml │ │ │ └── hosts │ │ └── production │ │ │ ├── group_vars │ │ │ └── app.yml │ │ │ └── hosts │ ├── library │ │ └── remote_filecopy.py │ ├── roles │ │ └── installapp │ │ │ ├── .travis.yml │ │ │ ├── README.md │ │ │ ├── defaults │ │ │ └── main.yml │ │ │ ├── handlers │ │ │ └── main.yml │ │ │ ├── meta │ │ │ └── main.yml │ │ │ ├── tasks │ │ │ └── main.yml │ │ │ ├── tests │ │ │ ├── inventory │ │ │ └── test.yml │ │ │ └── vars │ │ │ └── main.yml │ └── site.yml ├── hosts ├── osvariants.yml ├── variable-precedence-1 │ ├── inventories │ │ └── development │ │ │ ├── group_vars │ │ │ └── all.yml │ │ │ └── hosts │ └── site.yml ├── variable-precedence-2 │ ├── inventories │ │ └── development │ │ │ ├── group_vars │ │ │ ├── all.yml │ │ │ └── app.yml │ │ │ └── hosts │ └── site.yml ├── variable-precedence-3 │ ├── inventories │ │ └── development │ │ │ ├── group_vars │ │ │ ├── all.yml │ │ │ ├── centos.yml │ │ │ ├── dapp.yml │ │ │ └── newcentos.yml │ │ │ └── hosts │ └── site.yml └── variable-precedence-4 │ ├── inventories │ └── development │ │ ├── group_vars │ │ ├── all.yml │ │ ├── centos.yml │ │ ├── dapp.yml │ │ └── newcentos.yml │ │ ├── host_vars │ │ └── app01.dev.example.com.yml │ │ └── hosts │ └── site.yml ├── Chapter 8 ├── add_to_loadbalancer.sh ├── async.yml ├── async2.yml ├── delegate.yml ├── delegate2.yml ├── hosts ├── inlinevaultplaybook.yml ├── localhosts ├── localhosts2 ├── maxfail.yml ├── morehosts ├── prompt.yml ├── remove_from_loadbalancer.sh ├── runonce.yml ├── secret.yml ├── serial.yml ├── switches ├── tags.yml ├── templates │ └── nginx.conf.j2 └── vaultplaybook.yml ├── Chapter 9 ├── conditional-example │ ├── group_vars │ │ └── cumulusvx.yml │ ├── hosts │ └── portenable.yml ├── connection-example │ ├── cumulusvx_facts.yml │ ├── group_vars │ │ ├── cumulusvx.yml │ │ └── routers.yml │ ├── hosts │ └── ios_facts.yml └── environment-example │ ├── group_vars │ ├── bastion_cumulusvx.yml │ └── bastion_routers.yml │ └── hosts ├── LICENSE └── README.md /Chapter 10/aws.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Ensure key pair is present 5 | ec2_key: 6 | name: fale 7 | key_material: "{{ lookup('file', '~/.ssh/fale.pub') }}" 8 | - name: Gather information of the EC2 VPC net in eu-west-1 9 | ec2_vpc_net_facts: 10 | region: eu-west-1 11 | register: aws_simple_net 12 | - name: Gather information of the EC2 VPC subnet in eu-west-1 13 | ec2_vpc_subnet_facts: 14 | region: eu-west-1 15 | filters: 16 | vpc-id: '{{ aws_simple_net.vpcs.0.id }}' 17 | register: aws_simple_subnet 18 | - name: Ensure wssg Security Group is present 19 | ec2_group: 20 | name: wssg 21 | description: Web Security Group 22 | region: eu-west-1 23 | vpc_id: '{{ aws_simple_net.vpcs.0.id }}' 24 | rules: 25 | - proto: tcp 26 | from_port: 22 27 | to_port: 22 28 | cidr_ip: 0.0.0.0/0 29 | - proto: tcp 30 | from_port: 80 31 | to_port: 80 32 | cidr_ip: 0.0.0.0/0 33 | - proto: tcp 34 | from_port: 443 35 | to_port: 443 36 | cidr_ip: 0.0.0.0/0 37 | rules_egress: 38 | - proto: all 39 | cidr_ip: 0.0.0.0/0 40 | register: aws_simple_wssg 41 | - name: Setup instance 42 | ec2: 43 | assign_public_ip: true 44 | image: ami-3548444c 45 | region: eu-west-1 46 | exact_count: 1 47 | key_name: fale 48 | count_tag: 49 | Name: ws01.ansible2cookbook.com 50 | instance_tags: 51 | Name: ws01.ansible2cookbook.coms 52 | instance_type: t2.micro 53 | group_id: '{{ aws_simple_wssg.group_id }}' 54 | vpc_subnet_id: '{{ aws_simple_subnet.subnets.0.id }}' 55 | volumes: 56 | - device_name: /dev/sda1 57 | volume_type: gp2 58 | volume_size: 10 59 | delete_on_termination: True 60 | -------------------------------------------------------------------------------- /Chapter 10/azure.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Ensure the Storage Account is present 5 | azure_rm_storageaccount: 6 | resource_group: Testing 7 | name: mysa 8 | account_type: Standard_LRS 9 | - name: Ensure the Virtual Network is present 10 | azure_rm_virtualnetwork: 11 | resource_group: Testing 12 | name: myvn 13 | address_prefixes: "10.10.0.0/16" 14 | - name: Ensure the Subnet is present 15 | azure_rm_subnet: 16 | resource_group: Testing 17 | name: mysn 18 | address_prefix: "10.10.0.0/24" 19 | virtual_network: myvn 20 | - name: Ensure that the Public IP is set 21 | azure_rm_publicipaddress: 22 | resource_group: Testing 23 | allocation_method: Static 24 | name: myip 25 | - name: Ensure a Security Group allowing SSH is present 26 | azure_rm_securitygroup: 27 | resource_group: Testing 28 | name: mysg 29 | rules: 30 | - name: SSH 31 | protocol: Tcp 32 | destination_port_range: 22 33 | access: Allow 34 | priority: 101 35 | direction: Inbound 36 | - name: Ensure the NIC is present 37 | azure_rm_networkinterface: 38 | resource_group: Testing 39 | name: testnic001 40 | virtual_network: myvn 41 | subnet: mysn 42 | public_ip_name: myip 43 | security_group: mysg 44 | - name: Ensure the Virtual Machine is present 45 | azure_rm_virtualmachine: 46 | resource_group: Testing 47 | name: myvm01 48 | vm_size: Standard_D1 49 | storage_account: mysa 50 | storage_container: myvm01 51 | storage_blob: myvm01.vhd 52 | admin_username: admin 53 | admin_password: Password! 54 | network_interfaces: testnic001 55 | image: 56 | offer: CentOS 57 | publisher: OpenLogic 58 | sku: '8.0' 59 | version: latest 60 | -------------------------------------------------------------------------------- /Chapter 10/container.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | settings: 3 | conductor: 4 | base: centos:7 5 | project_name: http-server 6 | k8s_namespace: 7 | name: http-server 8 | description: An HTTP server 9 | display_name: HTTP server 10 | services: 11 | web: 12 | from: "centos:7" 13 | roles: 14 | - geerlingguy.apache 15 | ports: 16 | - "80:80" 17 | command: 18 | - "/usr/bin/dumb-init" 19 | - "/usr/sbin/apache2ctl" 20 | - "-D" 21 | - "FOREGROUND" 22 | dev_overrides: 23 | environment: 24 | - "DEBUG=1" 25 | -------------------------------------------------------------------------------- /Chapter 10/gce.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: create a instance 5 | gcp_compute_instance: 6 | name: TestMachine 7 | machine_type: n1-standard-1 8 | disks: 9 | - auto_delete: 'true' 10 | boot: 'true' 11 | initialize_params: 12 | source_image: family/centos-7 13 | disk_size_gb: 10 14 | zone: eu-west1-c 15 | auth_kind: serviceaccount 16 | service_account_file: "~/.config/gcloud/legacy_credentials/f.locati@opengate.biz/singlestore_bq.json" 17 | state: present 18 | -------------------------------------------------------------------------------- /Chapter 10/k8s-ns-show.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Get information from K8s 5 | k8s_info: 6 | api_version: v1 7 | kind: Namespace 8 | register: ns 9 | - name: Print info 10 | debug: 11 | var: ns 12 | -------------------------------------------------------------------------------- /Chapter 10/k8s-ns.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Ensure the myns namespace exists 5 | k8s: 6 | api_version: v1 7 | kind: Namespace 8 | name: myns 9 | state: present 10 | -------------------------------------------------------------------------------- /Chapter 10/k8s-svc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Ensure the Service mysvc is present 5 | k8s: 6 | state: present 7 | definition: 8 | apiVersion: v1 9 | kind: Service 10 | metadata: 11 | name: mysvc 12 | namespace: myns 13 | spec: 14 | selector: 15 | app: myapp 16 | service: mysvc 17 | ports: 18 | - protocol: TCP 19 | targetPort: 800 20 | name: port-80-tcp 21 | port: 80 22 | -------------------------------------------------------------------------------- /Chapter 10/openstack.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Ensure the SSH key is present on OpenStack 5 | os_keypair: 6 | state: present 7 | name: ansible_key 8 | public_key_file: "{{ '~' | expanduser }}/.ssh/id_rsa.pub" 9 | - name: Ensure we have a CentOS image 10 | get_url: 11 | url: http://cloud.centos.org/centos/8/x86_64/images/CentOS-8-GenericCloud-8.1.1911-20200113.3.x86_64.qcow2 12 | dest: /tmp/CentOS-8-GenericCloud-8.1.1911-20200113.3.x86_64.qcow2 13 | - name: Ensure the CentOS image is in OpenStack 14 | os_image: 15 | name: centos 16 | container_format: bare 17 | disk_format: qcow2 18 | state: present 19 | filename: /tmp/CentOS-8-GenericCloud-8.1.1911-20200113.3.x86_64.qcow2 20 | - name: Ensure the Network is present 21 | os_network: 22 | state: present 23 | name: mynet 24 | external: False 25 | shared: False 26 | register: net_out 27 | - name: Ensure the Subnetwork is present 28 | os_subnet: 29 | state: present 30 | network_name: "{{ net_out.id }}" 31 | name: mysubnet 32 | ip_version: 4 33 | cidr: 192.168.0.0/24 34 | gateway_ip: 192.168.0.1 35 | enable_dhcp: yes 36 | dns_nameservers: 37 | - 8.8.8.8 38 | - name: Ensure the Router is present 39 | os_router: 40 | state: present 41 | name: myrouter 42 | network: nova 43 | external_fixed_ips: 44 | - subnet: nova 45 | interfaces: 46 | - mysubnet 47 | - name: Ensure the Security Group is present 48 | os_security_group: 49 | state: present 50 | name: mysg 51 | - name: Ensure the Security Group allows ICMP traffic 52 | os_security_group_rule: 53 | security_group: mysg 54 | protocol: icmp 55 | remote_ip_prefix: 0.0.0.0/0 56 | - name: Ensure the Security Group allows SSH traffic 57 | os_security_group_rule: 58 | security_group: mysg 59 | protocol: tcp 60 | port_range_min: 22 61 | port_range_max: 22 62 | remote_ip_prefix: 0.0.0.0/0 63 | - name: Ensure the Instance exists 64 | os_server: 65 | state: present 66 | name: myInstance 67 | image: centos 68 | flavor: m1.small 69 | security_groups: mysg 70 | key_name: ansible_key 71 | nics: 72 | - net-id: "{{ net_out.id }}" 73 | -------------------------------------------------------------------------------- /Chapter 10/rax.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Ensure the my_machine exists 5 | rax: 6 | name: my_machine 7 | flavor: 4 8 | image: centos-8 9 | count: 1 10 | group: my_group 11 | wait: True 12 | -------------------------------------------------------------------------------- /Chapter 10/start-docker-container.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Start a container with a command 5 | docker_container: 6 | name: test-container 7 | image: alpine 8 | command: 9 | - echo 10 | - "Hello, World!" 11 | -------------------------------------------------------------------------------- /Chapter 11/check-mode.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - name: Touch a file 5 | file: 6 | path: /tmp/myfile 7 | state: touch 8 | -------------------------------------------------------------------------------- /Chapter 11/debug.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - shell: /usr/bin/uptime 5 | register: result 6 | - debug: 7 | var: result 8 | -------------------------------------------------------------------------------- /Chapter 11/debug2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - shell: /usr/bin/uptime 5 | register: result 6 | - debug: 7 | var: result 8 | verbosity: 2 9 | -------------------------------------------------------------------------------- /Chapter 11/helloworld.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | tasks: 4 | - debug: 5 | msg: "Hello, World!" 6 | -------------------------------------------------------------------------------- /Chapter 11/inventory: -------------------------------------------------------------------------------- 1 | [hosts] 2 | host1.example.com 3 | host2.example.com 4 | host3.example.com 5 | -------------------------------------------------------------------------------- /Chapter 11/print_facts.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | tasks: 4 | - name: Display all variables/facts known for a host 5 | debug: 6 | var: hostvars[inventory_hostname] 7 | -------------------------------------------------------------------------------- /Chapter 11/printvar.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | tasks: 4 | - debug: 5 | var: variable 6 | -------------------------------------------------------------------------------- /Chapter 11/remote.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | tasks: 4 | - name: Touch a file 5 | file: 6 | path: /tmp/myfile 7 | state: touch 8 | -------------------------------------------------------------------------------- /Chapter 11/syntaxcheck-fixed.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | tasks: 4 | - debug: 5 | msg: "Hello, World!" 6 | -------------------------------------------------------------------------------- /Chapter 11/syntaxcheck.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | tasks: 4 | - debug: 5 | msg: "Hello, World!" 6 | -------------------------------------------------------------------------------- /Chapter 2/appservers-emea.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: appservers_emea_zone 3 | remote_user: danieloh 4 | tasks: 5 | - name: simple connection test 6 | ping: 7 | -------------------------------------------------------------------------------- /Chapter 2/employee-all-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Parse the employees playbook 3 | hosts: localhost 4 | vars_files: 5 | - employees-all.yml 6 | 7 | tasks: 8 | - name: Print the variables 9 | debug: 10 | var: employees 11 | 12 | -------------------------------------------------------------------------------- /Chapter 2/employee-flow-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Parse the employees playbook 3 | hosts: localhost 4 | vars_files: 5 | - employees-flow.yml 6 | 7 | tasks: 8 | - name: Print the variables 9 | debug: 10 | var: employees 11 | 12 | -------------------------------------------------------------------------------- /Chapter 2/employee-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Parse the employees playbook 3 | hosts: localhost 4 | vars_files: 5 | - employees.yml 6 | 7 | tasks: 8 | - name: Print the variables 9 | debug: 10 | var: employees 11 | 12 | -------------------------------------------------------------------------------- /Chapter 2/employees-all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | servers: 3 | - frontend 4 | - backend 5 | - database 6 | - cache 7 | employees: 8 | - name: daniel 9 | fullname: Daniel Oh 10 | role: DevOps Evangelist 11 | level: Expert 12 | skills: 13 | - Kubernetes 14 | - Microservices 15 | - Ansible 16 | - Linux Container 17 | - name: michael 18 | fullname: Michael Smiths 19 | role: Enterprise Architect 20 | level: Advanced 21 | skills: 22 | - Cloud 23 | - Middleware 24 | - Windows 25 | - Storage 26 | Speciality: | 27 | Agile methodology 28 | Cloud-native app development practices 29 | Advanced enterprise DevOps practices 30 | -------------------------------------------------------------------------------- /Chapter 2/employees-flow.yml: -------------------------------------------------------------------------------- 1 | --- 2 | employees: [{"fullname": "Daniel Oh","level": "Expert","name": "daniel","role": "DevOps Evangelist","skills": ["Kubernetes","Microservices","Ansible","Linux Container"]},{"fullname": "Michael Smiths","level": "Advanced","name": "michael","role": "Enterprise Architect","skills":["Cloud","Middleware","Windows","Storage"]}] 3 | -------------------------------------------------------------------------------- /Chapter 2/employees.yml: -------------------------------------------------------------------------------- 1 | --- 2 | employees: 3 | - name: daniel 4 | fullname: Daniel Oh 5 | role: DevOps Evangelist 6 | level: Expert 7 | skills: 8 | - Kubernetes 9 | - Microservices 10 | - Ansible 11 | - Linux Container 12 | - name: michael 13 | fullname: Michael Smiths 14 | role: Enterprise Architect 15 | level: Advanced 16 | skills: 17 | - Cloud 18 | - Middleware 19 | - Windows 20 | - Storage 21 | -------------------------------------------------------------------------------- /Chapter 2/frontends-na.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: frontends_na_zone 3 | remote_user: danieloh 4 | tasks: 5 | - name: simple connection test 6 | ping: 7 | -------------------------------------------------------------------------------- /Chapter 2/hosts: -------------------------------------------------------------------------------- 1 | [frontends_na_zone] 2 | 192.168.81.142 3 | -------------------------------------------------------------------------------- /Chapter 2/jinja2-filtering1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Jinja2 filtering demo 1 3 | hosts: localhost 4 | 5 | tasks: 6 | - copy: 7 | src: multiple-document-strings.yaml 8 | dest: /tmp/multiple-document-strings.yaml 9 | - shell: cat /tmp/multiple-document-strings.yaml 10 | register: result 11 | - debug: 12 | msg: '{{ item }}' 13 | loop: '{{ result.stdout | from_yaml_all | list }}' 14 | -------------------------------------------------------------------------------- /Chapter 2/jinja2-filtering2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Jinja2 filtering demo 2 3 | hosts: localhost 4 | vars: 5 | tags: 6 | - key: job 7 | value: developer 8 | - key: language 9 | value: java 10 | 11 | tasks: 12 | - debug: 13 | msg: '{{ tags | items2dict }}' 14 | -------------------------------------------------------------------------------- /Chapter 2/jinja2-filtering3.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Jinja2 filtering demo 3 3 | hosts: localhost 4 | vars: 5 | ping_value: "{{ lookup('file', '/etc/hosts') }}" 6 | 7 | tasks: 8 | - debug: 9 | msg: "ping value is {{ ping_value }}" 10 | -------------------------------------------------------------------------------- /Chapter 2/multiple-document-strings.yaml: -------------------------------------------------------------------------------- 1 | tags: 2 | - key: job 3 | value: developer 4 | - key: language 5 | value: java 6 | -------------------------------------------------------------------------------- /Chapter 2/production-inventory: -------------------------------------------------------------------------------- 1 | [frontends_na_zone] 2 | frontend1-na.example.com 3 | frontend2-na.example.com 4 | 5 | [frontends_emea_zone] 6 | frontend1-emea.example.com 7 | frontend2-emea.example.com 8 | 9 | [appservers_na_zone] 10 | appserver1-na.example.com 11 | appserver2-na.example.com 12 | 13 | [appservers_emea_zone] 14 | appserver1-emea.example.com 15 | appserver2-emea.example.com 16 | -------------------------------------------------------------------------------- /Chapter 2/redis-playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Display redis variables 3 | hosts: all 4 | 5 | vars: 6 | redis: 7 | server: cacheserver01.example.com 8 | port: 6379 9 | slaveof: cacheserver02.example.com 10 | 11 | tasks: 12 | - name: Display the redis port 13 | debug: 14 | #var: redis 15 | msg: "The redis port for {{ redis.server }} is {{ redis.port }}" 16 | -------------------------------------------------------------------------------- /Chapter 2/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - import_playbook: frontends-na.yml 3 | - import_playbook: appservers-emea.yml 4 | -------------------------------------------------------------------------------- /Chapter 2/update-apache-version.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: My first Ansible playbook 3 | hosts: all 4 | become: yes 5 | 6 | tasks: 7 | - name: Update the latest of an Apache Web Server 8 | yum: 9 | name: httpd 10 | state: latest 11 | notify: 12 | - Restart an Apache Web Server 13 | 14 | handlers: 15 | - name: Restart an Apache Web Server 16 | service: 17 | name: httpd 18 | state: restarted 19 | 20 | -------------------------------------------------------------------------------- /Chapter 3/groupvars1-hostgroups-ini: -------------------------------------------------------------------------------- 1 | loadbalancer.example.com 2 | 3 | [frontends] 4 | frt01.example.com 5 | frt02.example.com 6 | 7 | [frontends:vars] 8 | https_port=8443 9 | lb_vip=lb.example.com 10 | 11 | [apps] 12 | app01.example.com 13 | app02.example.com 14 | 15 | [databases] 16 | dbms01.example.com 17 | dbms02.example.com 18 | -------------------------------------------------------------------------------- /Chapter 3/hostgroups-children-ini: -------------------------------------------------------------------------------- 1 | loadbalancer.example.com 2 | 3 | [frontends] 4 | frt01.example.com 5 | frt02.example.com 6 | 7 | [apps] 8 | app01.example.com 9 | app02.example.com 10 | 11 | [databases] 12 | dbms01.example.com 13 | dbms02.example.com 14 | 15 | [centos:children] 16 | apps 17 | databases 18 | 19 | [ubuntu:children] 20 | frontends 21 | -------------------------------------------------------------------------------- /Chapter 3/hostgroups-children-vars-ini: -------------------------------------------------------------------------------- 1 | loadbalancer.example.com 2 | 3 | [frontends] 4 | frt01.example.com 5 | frt02.example.com 6 | 7 | [frontends:vars] 8 | testvar=childgroup 9 | 10 | [apps] 11 | app01.example.com 12 | app02.example.com 13 | 14 | [databases] 15 | dbms01.example.com 16 | dbms02.example.com 17 | 18 | [centos:children] 19 | apps 20 | databases 21 | 22 | [ubuntu:children] 23 | frontends 24 | 25 | [ubuntu:vars] 26 | testvar=group 27 | -------------------------------------------------------------------------------- /Chapter 3/hostgroups-ini: -------------------------------------------------------------------------------- 1 | loadbalancer.example.com 2 | 3 | [frontends] 4 | frt01.example.com 5 | frt02.example.com 6 | 7 | [apps] 8 | app01.example.com 9 | app02.example.com 10 | 11 | [databases] 12 | dbms01.example.com 13 | dbms02.example.com 14 | -------------------------------------------------------------------------------- /Chapter 3/hostgroups-yml: -------------------------------------------------------------------------------- 1 | all: 2 | hosts: 3 | loadbalancer.example.com: 4 | children: 5 | centos: 6 | children: 7 | apps: 8 | hosts: 9 | app01.example.com: 10 | app02.example.com: 11 | databases: 12 | hosts: 13 | dbms01.example.com: 14 | dbms02.example.com: 15 | ubuntu: 16 | children: 17 | frontends: 18 | hosts: 19 | frt01.example.com: 20 | frt02.example.com: 21 | -------------------------------------------------------------------------------- /Chapter 3/hosts: -------------------------------------------------------------------------------- 1 | [frontends] 2 | frt01.example.com https_port=8443 3 | frt02.example.com http_proxy=proxy.example.com 4 | 5 | [frontends:vars] 6 | ntp_server=ntp.frt.example.com 7 | proxy=proxy.frt.example.com 8 | 9 | [apps] 10 | app01.example.com 11 | app02.example.com 12 | 13 | [webapp:children] 14 | frontends 15 | apps 16 | 17 | [webapp:vars] 18 | proxy_server=proxy.webapp.example.com 19 | health_check_retry=3 20 | health_check_interal=60 21 | -------------------------------------------------------------------------------- /Chapter 3/hostvars1-hostgroups-ini: -------------------------------------------------------------------------------- 1 | loadbalancer.example.com 2 | 3 | [frontends] 4 | frt01.example.com https_port=8443 lb_vip=lb.example.com 5 | frt02.example.com https_port=8443 lb_vip=lb.example.com 6 | 7 | [apps] 8 | app01.example.com 9 | app02.example.com 10 | 11 | [databases] 12 | dbms01.example.com 13 | dbms02.example.com 14 | -------------------------------------------------------------------------------- /Chapter 3/hostvars2-hostgroups-ini: -------------------------------------------------------------------------------- 1 | loadbalancer.example.com 2 | 3 | [frontends] 4 | frt01.example.com https_port=8444 5 | frt02.example.com 6 | 7 | [frontends:vars] 8 | https_port=8443 9 | lb_vip=lb.example.com 10 | 11 | [apps] 12 | app01.example.com 13 | app02.example.com 14 | 15 | [databases] 16 | dbms01.example.com 17 | dbms02.example.com 18 | -------------------------------------------------------------------------------- /Chapter 3/hostvars2-hostgroups-yml: -------------------------------------------------------------------------------- 1 | all: 2 | hosts: 3 | loadbalancer.example.com: 4 | children: 5 | centos: 6 | children: 7 | apps: 8 | hosts: 9 | app01.example.com: 10 | app02.example.com: 11 | databases: 12 | hosts: 13 | dbms01.example.com: 14 | dbms02.example.com: 15 | ubuntu: 16 | children: 17 | frontends: 18 | hosts: 19 | frt01.example.com: 20 | https_port: 8444 21 | frt02.example.com: 22 | vars: 23 | https_port: 8443 24 | lb_vip: lb.example.com 25 | -------------------------------------------------------------------------------- /Chapter 3/my_inventory: -------------------------------------------------------------------------------- 1 | target1.example.com ansible_host=192.168.81.142 ansible_port=3333 2 | 3 | target2.example.com ansible_port=3333 ansible_user=danieloh 4 | 5 | target3.example.com ansible_host=192.168.81.143 ansible_port=5555 6 | -------------------------------------------------------------------------------- /Chapter 3/my_inventory.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ungrouped: 3 | hosts: 4 | target1.example.com: 5 | ansible_host: 192.168.81.142 6 | ansible_port: 3333 7 | target2.example.com: 8 | ansible_port: 3333 9 | ansible_user: danieloh 10 | target3.example.com: 11 | ansible_host: 192.168.81.143 12 | ansible_port: 5555 13 | -------------------------------------------------------------------------------- /Chapter 3/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: A simple playbook for demonstrating inventory patterns 3 | hosts: all 4 | 5 | tasks: 6 | - name: Ping each host 7 | ping: 8 | -------------------------------------------------------------------------------- /Chapter 3/static-groups-mix-ini: -------------------------------------------------------------------------------- 1 | [webservers] 2 | 3 | [centos:children] 4 | webservers 5 | -------------------------------------------------------------------------------- /Chapter 3/vartree/group_vars/frontends.yml: -------------------------------------------------------------------------------- 1 | --- 2 | https_port: 8443 3 | lb_vip: lb.example.com 4 | -------------------------------------------------------------------------------- /Chapter 3/vartree/host_vars/frt01.example.com.yml: -------------------------------------------------------------------------------- 1 | --- 2 | https_port: 8444 3 | -------------------------------------------------------------------------------- /Chapter 3/vartree/inventory: -------------------------------------------------------------------------------- 1 | loadbalancer.example.com 2 | 3 | [frontends] 4 | frt01.example.com 5 | frt02.example.com 6 | 7 | [apps] 8 | app01.example.com 9 | app02.example.com 10 | 11 | [databases] 12 | dbms01.example.com 13 | dbms02.example.com 14 | -------------------------------------------------------------------------------- /Chapter 3/vartree2/group_vars/frontends/https_port.yml: -------------------------------------------------------------------------------- 1 | --- 2 | https_port: 8443 3 | -------------------------------------------------------------------------------- /Chapter 3/vartree2/group_vars/frontends/lb_vip.yml: -------------------------------------------------------------------------------- 1 | --- 2 | lb_vip: lb.example.com 3 | -------------------------------------------------------------------------------- /Chapter 3/vartree2/host_vars/frt01.example.com/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | https_port: 8444 3 | -------------------------------------------------------------------------------- /Chapter 3/vartree2/inventory: -------------------------------------------------------------------------------- 1 | loadbalancer.example.com 2 | 3 | [frontends] 4 | frt01.example.com 5 | frt02.example.com 6 | 7 | [apps] 8 | app01.example.com 9 | app02.example.com 10 | 11 | [databases] 12 | dbms01.example.com 13 | dbms02.example.com 14 | -------------------------------------------------------------------------------- /Chapter 4/blocks-error.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate block error handling 3 | hosts: frontends 4 | 5 | tasks: 6 | - name: block to handle errors 7 | block: 8 | - name: Perform a successful task 9 | debug: 10 | msg: 'Normally executing....' 11 | - name: Deliberately create an error 12 | command: /bin/whatever 13 | - name: This task should not run if the previous one results in an error 14 | debug: 15 | msg: 'Never print this message if the above command fails!!!!' 16 | rescue: 17 | - name: Catch the error (and perform recovery actions) 18 | debug: 19 | msg: 'Caught the error' 20 | - name: Deliberately create another error 21 | command: /bin/whatever 22 | - name: This task should not run if the previous one results in an error 23 | debug: 24 | msg: 'Do not print this message if the above command fails!!!!' 25 | always: 26 | - name: This task always runs! 27 | debug: 28 | msg: "Tasks in this part of the play will be ALWAYS executed!!!!" 29 | -------------------------------------------------------------------------------- /Chapter 4/blocks.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Conditional block play 3 | hosts: all 4 | become: true 5 | 6 | tasks: 7 | - name: Install and configure Apache 8 | block: 9 | - name: Install the Apache package 10 | dnf: 11 | name: httpd 12 | state: installed 13 | - name: Install the templated configuration to a dummy location 14 | template: 15 | src: templates/src.j2 16 | dest: /tmp/my.conf 17 | - name: Start the httpd service 18 | service: 19 | name: httpd 20 | state: started 21 | enabled: True 22 | when: ansible_facts['distribution'] == 'Fedora' 23 | 24 | 25 | -------------------------------------------------------------------------------- /Chapter 4/condition.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to patch only CentOS systems 3 | hosts: all 4 | become: true 5 | 6 | tasks: 7 | - name: Patch CentOS systems 8 | yum: 9 | name: httpd 10 | state: latest 11 | when: ansible_facts['distribution'] == "CentOS" 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter 4/condition2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to patch only CentOS systems 3 | hosts: all 4 | become: true 5 | 6 | tasks: 7 | - name: Patch CentOS systems 8 | yum: 9 | name: httpd 10 | state: latest 11 | when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") 12 | 13 | 14 | -------------------------------------------------------------------------------- /Chapter 4/condition3.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to patch only CentOS systems 3 | hosts: localhost 4 | become: true 5 | 6 | tasks: 7 | - name: Gather directory listing from local system 8 | shell: "ls -l" 9 | register: shellresult 10 | 11 | - name: Alert if we find a hosts file 12 | debug: 13 | msg: "Found hosts file!" 14 | when: '"hosts" in shellresult.stdout' 15 | 16 | -------------------------------------------------------------------------------- /Chapter 4/debug.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate the debug strategy 3 | hosts: frt01.example.com 4 | strategy: debug 5 | debugger: on_failed 6 | gather_facts: no 7 | vars: 8 | name: daniel 9 | 10 | tasks: 11 | - name: Generate an error by referencing an undefined variable 12 | ping: data={{ mobile }} 13 | -------------------------------------------------------------------------------- /Chapter 4/handlers1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Handler demo 1 3 | hosts: frt01.example.com 4 | gather_facts: no 5 | become: yes 6 | 7 | tasks: 8 | - name: Update Apache configuration 9 | template: 10 | src: template.j2 11 | dest: /etc/httpd/httpd.conf 12 | notify: Restart Apache 13 | 14 | handlers: 15 | - name: Restart Apache 16 | service: 17 | name: httpd 18 | state: restarted 19 | -------------------------------------------------------------------------------- /Chapter 4/handlers2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Handler demo 1 3 | hosts: frt01.example.com 4 | gather_facts: no 5 | become: yes 6 | 7 | handlers: 8 | - name: restart chronyd 9 | service: 10 | name: chronyd 11 | state: restarted 12 | listen: "restart all services" 13 | - name: restart apache 14 | service: 15 | name: httpd 16 | state: restarted 17 | listen: "restart all services" 18 | 19 | tasks: 20 | - name: restart all services 21 | command: echo "this task will restart all services" 22 | notify: "restart all services" 23 | -------------------------------------------------------------------------------- /Chapter 4/hosts: -------------------------------------------------------------------------------- 1 | [frontends] 2 | frt01.example.com https_port=8443 3 | frt02.example.com http_proxy=proxy.example.com 4 | 5 | [frontends:vars] 6 | ntp_server=ntp.frt.example.com 7 | proxy=proxy.frt.example.com 8 | 9 | [apps] 10 | app01.example.com 11 | app02.example.com 12 | 13 | [webapp:children] 14 | frontends 15 | apps 16 | 17 | [webapp:vars] 18 | proxy_server=proxy.webapp.example.com 19 | health_check_retry=3 20 | health_check_interal=60 21 | -------------------------------------------------------------------------------- /Chapter 4/installapache.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Apache 3 | hosts: frt01.example.com 4 | gather_facts: no 5 | become: yes 6 | 7 | tasks: 8 | - name: Install Apache package 9 | yum: 10 | name: httpd 11 | state: latest 12 | - name: Open firewall for Apache 13 | firewalld: 14 | service: "{{ item }}" 15 | permanent: yes 16 | state: enabled 17 | immediate: yes 18 | loop: 19 | - "http" 20 | - "https" 21 | - name: Restart and enable the service 22 | service: 23 | name: httpd 24 | state: restarted 25 | enabled: yes 26 | -------------------------------------------------------------------------------- /Chapter 4/loop1.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simple loop demo play 3 | hosts: frt01.example.com 4 | 5 | tasks: 6 | - name: Echo a value from the loop 7 | command: echo "{{ item }}" 8 | loop: 9 | - 1 10 | - 2 11 | - 3 12 | - 4 13 | - 5 14 | - 6 15 | 16 | -------------------------------------------------------------------------------- /Chapter 4/loop2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simple loop demo play 3 | hosts: frt01.example.com 4 | 5 | tasks: 6 | - name: Echo a value from the loop 7 | command: echo "{{ item }}" 8 | loop: 9 | - 1 10 | - 2 11 | - 3 12 | - 4 13 | - 5 14 | - 6 15 | when: item|int > 3 16 | 17 | -------------------------------------------------------------------------------- /Chapter 4/loop3.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simple loop demo play 3 | hosts: frt01.example.com 4 | 5 | tasks: 6 | - name: Echo a value from the loop 7 | command: echo "{{ item }}" 8 | loop: 9 | - 1 10 | - 2 11 | - 3 12 | - 4 13 | - 5 14 | - 6 15 | when: item|int > 3 16 | register: loopresult 17 | 18 | - name: Print the results from the loop 19 | debug: 20 | var: loopresult 21 | -------------------------------------------------------------------------------- /Chapter 4/loopmain.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate nested loops 3 | hosts: localhost 4 | 5 | tasks: 6 | - name: Outer loop 7 | include_tasks: loopsubtask.yml 8 | loop: 9 | - a 10 | - b 11 | - c 12 | loop_control: 13 | loop_var: second_item 14 | -------------------------------------------------------------------------------- /Chapter 4/loopsubtask.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Inner loop 3 | debug: 4 | msg: "second item={{ second_item }} first item={{ item }}" 5 | loop: 6 | - 100 7 | - 200 8 | - 300 9 | -------------------------------------------------------------------------------- /Chapter 4/myplaybook.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: frontends 3 | remote_user: danieloh 4 | 5 | tasks: 6 | - name: simple connection test 7 | ping: 8 | remote_user: danieloh 9 | 10 | - name: run a simple command 11 | shell: /bin/ls -al /nonexistent 12 | ignore_errors: True 13 | -------------------------------------------------------------------------------- /Chapter 4/playandtask.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play 1 - configure the frontend servers 3 | hosts: frontends 4 | become: yes 5 | 6 | tasks: 7 | - name: Install the Apache package 8 | yum: 9 | name: httpd 10 | state: latest 11 | - name: Start the Apache server 12 | service: 13 | name: httpd 14 | state: started 15 | 16 | - name: Play 2 - configure the appliation servers 17 | hosts: apps 18 | become: true 19 | 20 | tasks: 21 | - name: Install Tomcat 22 | yum: 23 | name: tomcat 24 | state: latest 25 | - name: Start the Tomcat server 26 | service: 27 | name: tomcat 28 | state: started 29 | -------------------------------------------------------------------------------- /Chapter 4/playbookvsadhoc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: frontends 3 | remote_user: doh 4 | 5 | handlers: 6 | - name: restart apache web server 7 | service: 8 | name: httpd 9 | state: restarted 10 | listen: "restart all services" 11 | 12 | tasks: 13 | - name: restart all services 14 | debug: 15 | msg: "Restarting" 16 | notify: "restart all services" 17 | -------------------------------------------------------------------------------- /Chapter 4/role-example1/hosts: -------------------------------------------------------------------------------- 1 | [frontends] 2 | frt01.example.com https_port=8443 3 | frt02.example.com http_proxy=proxy.example.com 4 | 5 | [frontends:vars] 6 | ntp_server=ntp.frt.example.com 7 | proxy=proxy.frt.example.com 8 | 9 | [apps] 10 | app01.example.com 11 | app02.example.com 12 | 13 | [webapp:children] 14 | frontends 15 | apps 16 | 17 | [webapp:vars] 18 | proxy_server=proxy.webapp.example.com 19 | health_check_retry=3 20 | health_check_interal=60 21 | -------------------------------------------------------------------------------- /Chapter 4/role-example1/roles/installapache/tasks/centos.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Apache using yum 3 | yum: 4 | name: "httpd" 5 | state: latest 6 | - name: Start the Apache server 7 | service: 8 | name: httpd 9 | state: started 10 | -------------------------------------------------------------------------------- /Chapter 4/role-example1/roles/installapache/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: import a tasks based on OS platform 3 | import_tasks: centos.yml 4 | when: ansible_distribution == 'CentOS' 5 | - import_tasks: ubuntu.yml 6 | when: ansible_distribution == 'Ubuntu' 7 | -------------------------------------------------------------------------------- /Chapter 4/role-example1/roles/installapache/tasks/ubuntu.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Apache using apt 3 | apt: 4 | name: "apache2" 5 | state: latest 6 | - name: Start the Apache server 7 | service: 8 | name: apache2 9 | state: started 10 | -------------------------------------------------------------------------------- /Chapter 4/role-example1/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Install Apache using a role 3 | hosts: frontends 4 | become: true 5 | 6 | roles: 7 | - installapache 8 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/hosts: -------------------------------------------------------------------------------- 1 | [frontends] 2 | frt01.example.com https_port=8443 3 | frt02.example.com http_proxy=proxy.example.com 4 | 5 | [frontends:vars] 6 | ntp_server=ntp.frt.example.com 7 | proxy=proxy.frt.example.com 8 | 9 | [apps] 10 | app01.example.com 11 | app02.example.com 12 | 13 | [webapp:children] 14 | frontends 15 | apps 16 | 17 | [webapp:vars] 18 | proxy_server=proxy.webapp.example.com 19 | health_check_retry=3 20 | health_check_interal=60 21 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/linuxtype/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: 3 | - role: version 4 | - role: network 5 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/network/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | allow_duplicates: true 3 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/network/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Print type variable 3 | debug: 4 | var: type 5 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/platform/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependencies: 3 | - role: linuxtype 4 | type: "centos" 5 | - role: linuxtype 6 | type: "ubuntu" 7 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/testrole/.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/ -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/testrole/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 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/testrole/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for testrole -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/testrole/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for testrole -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/testrole/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 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/testrole/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for testrole -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/testrole/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/testrole/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - testrole -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/testrole/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for testrole -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/version/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | allow_duplicates: true 3 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/roles/version/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Print type variable 3 | debug: 4 | var: type 5 | -------------------------------------------------------------------------------- /Chapter 4/role-example2/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Role variables and meta playbook 3 | hosts: frt01.example.com 4 | 5 | roles: 6 | - platform 7 | -------------------------------------------------------------------------------- /Chapter 4/staticvsdynamicroles.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: frontends 3 | 4 | tasks: 5 | - import_role: 6 | name: common 7 | - include_role: 8 | name: approle 9 | -------------------------------------------------------------------------------- /Chapter 4/template.j2: -------------------------------------------------------------------------------- 1 | 2 | ServerRoot "/etc/httpd" 3 | 4 | Listen 80 5 | 6 | Include conf.modules.d/*.conf 7 | 8 | User apache 9 | Group apache 10 | 11 | 12 | ServerAdmin root@localhost 13 | 14 | 15 | 16 | AllowOverride none 17 | Require all denied 18 | 19 | 20 | 21 | DocumentRoot "/var/www/html" 22 | 23 | 24 | AllowOverride None 25 | Require all granted 26 | 27 | 28 | 29 | Options Indexes FollowSymLinks 30 | 31 | AllowOverride None 32 | 33 | Require all granted 34 | 35 | 36 | 37 | DirectoryIndex index.html 38 | 39 | 40 | 41 | Require all denied 42 | 43 | 44 | ErrorLog "logs/error_log" 45 | 46 | LogLevel warn 47 | 48 | 49 | LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 50 | LogFormat "%h %l %u %t \"%r\" %>s %b" common 51 | 52 | 53 | LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio 54 | 55 | 56 | 57 | CustomLog "logs/access_log" combined 58 | 59 | 60 | 61 | 62 | 63 | ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" 64 | 65 | 66 | 67 | 68 | AllowOverride None 69 | Options None 70 | Require all granted 71 | 72 | 73 | 74 | TypesConfig /etc/mime.types 75 | 76 | AddType application/x-compress .Z 77 | AddType application/x-gzip .gz .tgz 78 | 79 | 80 | 81 | AddType text/html .shtml 82 | AddOutputFilter INCLUDES .shtml 83 | 84 | 85 | AddDefaultCharset UTF-8 86 | 87 | 88 | MIMEMagicFile conf/magic 89 | 90 | 91 | 92 | EnableSendfile on 93 | 94 | IncludeOptional conf.d/*.conf 95 | -------------------------------------------------------------------------------- /Chapter 4/templates/src.j2: -------------------------------------------------------------------------------- 1 | Hello World! 2 | -------------------------------------------------------------------------------- /Chapter 5/args.json: -------------------------------------------------------------------------------- 1 | { 2 | "ANSIBLE_MODULE_ARGS": { 3 | "source": "/tmp/foo", 4 | "dest": "/tmp/bar" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Chapter 5/better_remote_filecopy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | 4 | # Copyright: (c) 2018, Jesse Keating 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | ANSIBLE_METADATA = {'metadata_version': '1.1', 8 | 'status': ['preview'], 9 | 'supported_by': 'community'} 10 | 11 | DOCUMENTATION = ''' 12 | --- 13 | module: remote_filecopy 14 | version_added: "2.9" 15 | short_description: Copy a file on the remote host 16 | description: 17 | - The remote_copy module copies a file on the remote host from a given source to a provided destination. 18 | options: 19 | source: 20 | description: 21 | - Path to a file on the source file on the remote host 22 | required: True 23 | dest: 24 | description: 25 | - Path to the destination on the remote host for the copy 26 | required: True 27 | author: 28 | - Jesse Keating (@omgjlk) 29 | ''' 30 | EXAMPLES = ''' 31 | # Example from Ansible Playbooks 32 | - name: backup a config file 33 | remote_copy: 34 | source: /etc/herp/derp.conf 35 | dest: /root/herp-derp.conf.bak 36 | ''' 37 | RETURN = ''' 38 | source: 39 | description: source file used for the copy 40 | returned: success 41 | type: str 42 | sample: "/path/to/file.name" 43 | dest: 44 | description: destination of the copy 45 | returned: success 46 | type: str 47 | sample: "/path/to/destination.file" 48 | gid: 49 | description: group ID of destination target 50 | returned: success 51 | type: int 52 | sample: 502 53 | group: 54 | description: group name of destination target 55 | returned: success 56 | type: str 57 | sample: "users" 58 | uid: 59 | description: owner ID of destination target 60 | returned: success 61 | type: int 62 | sample: 502 63 | owner: 64 | description: owner name of destination target 65 | returned: success 66 | type: str 67 | sample: "fred" 68 | mode: 69 | description: permissions of the destination target 70 | returned: success 71 | type: int 72 | sample: 0644 73 | size: 74 | description: size of destination target 75 | returned: success 76 | type: int 77 | sample: 20 78 | state: 79 | description: state of destination target 80 | returned: success 81 | type: str 82 | sample: "file" 83 | ''' 84 | import shutil 85 | 86 | def main(): 87 | module = AnsibleModule( 88 | argument_spec = dict( 89 | source=dict(required=True, type='str'), 90 | dest=dict(required=True, type='str') 91 | ), 92 | ) 93 | try: 94 | shutil.copy(module.params['source'], module.params['dest']) 95 | except: 96 | module.fail_json(msg="Failed to copy file") 97 | 98 | module.exit_json(changed=True) 99 | 100 | from ansible.module_utils.basic import * 101 | if __name__ == '__main__': 102 | main() 103 | -------------------------------------------------------------------------------- /Chapter 5/hosts: -------------------------------------------------------------------------------- 1 | [frontends] 2 | frt01.example.com 3 | 4 | [appservers] 5 | app01.example.com 6 | -------------------------------------------------------------------------------- /Chapter 5/remote_filecopy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | 4 | # Copyright: (c) 2018, Jesse Keating 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | ANSIBLE_METADATA = {'metadata_version': '1.1', 8 | 'status': ['preview'], 9 | 'supported_by': 'community'} 10 | 11 | DOCUMENTATION = ''' 12 | --- 13 | module: remote_filecopy 14 | version_added: "2.9" 15 | short_description: Copy a file on the remote host 16 | description: 17 | - The remote_copy module copies a file on the remote host from a given source to a provided destination. 18 | options: 19 | source: 20 | description: 21 | - Path to a file on the source file on the remote host 22 | required: True 23 | dest: 24 | description: 25 | - Path to the destination on the remote host for the copy 26 | required: True 27 | author: 28 | - Jesse Keating (@omgjlk) 29 | ''' 30 | EXAMPLES = ''' 31 | # Example from Ansible Playbooks 32 | - name: backup a config file 33 | remote_copy: 34 | source: /etc/herp/derp.conf 35 | dest: /root/herp-derp.conf.bak 36 | ''' 37 | RETURN = ''' 38 | source: 39 | description: source file used for the copy 40 | returned: success 41 | type: str 42 | sample: "/path/to/file.name" 43 | dest: 44 | description: destination of the copy 45 | returned: success 46 | type: str 47 | sample: "/path/to/destination.file" 48 | gid: 49 | description: group ID of destination target 50 | returned: success 51 | type: int 52 | sample: 502 53 | group: 54 | description: group name of destination target 55 | returned: success 56 | type: str 57 | sample: "users" 58 | uid: 59 | description: owner ID of destination target 60 | returned: success 61 | type: int 62 | sample: 502 63 | owner: 64 | description: owner name of destination target 65 | returned: success 66 | type: str 67 | sample: "fred" 68 | mode: 69 | description: permissions of the destination target 70 | returned: success 71 | type: int 72 | sample: 0644 73 | size: 74 | description: size of destination target 75 | returned: success 76 | type: int 77 | sample: 20 78 | state: 79 | description: state of destination target 80 | returned: success 81 | type: str 82 | sample: "file" 83 | ''' 84 | 85 | import shutil 86 | 87 | def main(): 88 | module = AnsibleModule( 89 | argument_spec = dict( 90 | source=dict(required=True, type='str'), 91 | dest=dict(required=True, type='str') 92 | ), 93 | ) 94 | shutil.copy(module.params['source'], 95 | module.params['dest']) 96 | 97 | module.exit_json(changed=True) 98 | 99 | from ansible.module_utils.basic import * 100 | if __name__ == '__main__': 101 | main() 102 | -------------------------------------------------------------------------------- /Chapter 5/retval.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simple play to demonstrate a return value 3 | hosts: localhost 4 | 5 | tasks: 6 | - name: Perform a simple module based task 7 | ping: 8 | register: pingresult 9 | 10 | - name: Display the result 11 | debug: 12 | var: pingresult 13 | -------------------------------------------------------------------------------- /Chapter 5/testplaybook/hosts: -------------------------------------------------------------------------------- 1 | [frontends] 2 | frt01.example.com 3 | 4 | [appservers] 5 | app01.example.com 6 | -------------------------------------------------------------------------------- /Chapter 5/testplaybook/library/remote_filecopy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | import shutil 4 | 5 | # Copyright: (c) 2018, Jesse Keating 6 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 7 | 8 | ANSIBLE_METADATA = {'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community'} 11 | 12 | DOCUMENTATION = ''' 13 | --- 14 | module: remote_filecopy 15 | version_added: "2.9" 16 | short_description: Copy a file on the remote host 17 | description: 18 | - The remote_copy module copies a file on the remote host from a given source to a provided destination. 19 | options: 20 | source: 21 | description: 22 | - Path to a file on the source file on the remote host 23 | required: True 24 | dest: 25 | description: 26 | - Path to the destination on the remote host for the copy 27 | required: True 28 | author: 29 | - Jesse Keating 30 | ''' 31 | EXAMPLES = ''' 32 | # Example from Ansible Playbooks 33 | - name: backup a config file 34 | remote_copy: 35 | source: /etc/herp/derp.conf 36 | dest: /root/herp-derp.conf.bak 37 | ''' 38 | RETURN = ''' 39 | source: 40 | description: source file used for the copy 41 | returned: success 42 | type: string 43 | sample: "/path/to/file.name" 44 | dest: 45 | description: destination of the copy 46 | returned: success 47 | type: string 48 | sample: "/path/to/destination.file" 49 | gid: 50 | description: group ID of destination target 51 | returned: success 52 | type: int 53 | sample: 502 54 | group: 55 | description: group name of destination target 56 | returned: success 57 | type: string 58 | sample: "users" 59 | uid: 60 | description: owner ID of destination target 61 | returned: success 62 | type: int 63 | sample: 502 64 | owner: 65 | description: owner name of destination target 66 | returned: success 67 | type: string 68 | sample: "fred" 69 | mode: 70 | description: permissions of the destination target 71 | returned: success 72 | type: int 73 | sample: 0644 74 | size: 75 | description: size of destination target 76 | returned: success 77 | type: int 78 | sample: 20 79 | state: 80 | description: state of destination target 81 | returned: success 82 | type: string 83 | sample: "file" 84 | ''' 85 | 86 | def main(): 87 | module = AnsibleModule( 88 | argument_spec = dict( 89 | source=dict(required=True, type='str'), 90 | dest=dict(required=True, type='str') 91 | ), 92 | ) 93 | shutil.copy(module.params['source'], 94 | module.params['dest']) 95 | 96 | module.exit_json(changed=True) 97 | 98 | from ansible.module_utils.basic import * 99 | if __name__ == '__main__': 100 | main() 101 | 102 | -------------------------------------------------------------------------------- /Chapter 5/testplaybook/testplaybook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Playbook to test custom module 3 | hosts: all 4 | 5 | tasks: 6 | - name: Test the custom module 7 | remote_filecopy: 8 | source: /tmp/foo 9 | dest: /tmp/bar 10 | register: testresult 11 | 12 | - name: Print the test result data 13 | debug: 14 | var: testresult 15 | -------------------------------------------------------------------------------- /Chapter 6/filter_plugins/custom_filter.py: -------------------------------------------------------------------------------- 1 | # (c) 2020, James Freeman 2 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 3 | def improve_automation(a): 4 | return a.replace("Puppet", "Ansible") 5 | class FilterModule(object): 6 | '''improve_automation filters''' 7 | def filters(self): 8 | return {'improve_automation': improve_automation} 9 | -------------------------------------------------------------------------------- /Chapter 6/filter_plugins/custom_filter.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Practical-Ansible-2/cd6c4532f4d238bd67a34a8d14081de6feea9c00/Chapter 6/filter_plugins/custom_filter.pyc -------------------------------------------------------------------------------- /Chapter 6/hosts: -------------------------------------------------------------------------------- 1 | [frontends] 2 | frt01.example.com 3 | 4 | [appservers] 5 | app01.example.com 6 | -------------------------------------------------------------------------------- /Chapter 6/lookup_plugins/firstchar.py: -------------------------------------------------------------------------------- 1 | # (c) 2020, James Freeman 2 | # (c) 2012, Daniel Hokka Zakrisson 3 | # (c) 2017 Ansible Project 4 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 5 | from __future__ import (absolute_import, division, print_function) 6 | __metaclass__ = type 7 | 8 | DOCUMENTATION = """ 9 | lookup: firstchar 10 | author: James Freeman 11 | version_added: "2.9" 12 | short_description: read the first character of file contents 13 | description: 14 | - This lookup returns the first character of the contents from a file on the Ansible controller's file system. 15 | options: 16 | _terms: 17 | description: path(s) of files to read 18 | required: True 19 | notes: 20 | - if read in variable context, the file can be interpreted as YAML if the content is valid to the parser. 21 | - this lookup does not understand 'globing', use the fileglob lookup instead. 22 | """ 23 | 24 | EXAMPLES = """ 25 | - debug: msg="the first character in foo.txt is {{lookup('firstchar', '/etc/foo.txt') }}" 26 | 27 | """ 28 | 29 | RETURN = """ 30 | _raw: 31 | description: 32 | - first character of content of file(s) 33 | """ 34 | 35 | from ansible.errors import AnsibleError, AnsibleParserError 36 | from ansible.plugins.lookup import LookupBase 37 | from ansible.utils.display import Display 38 | 39 | display = Display() 40 | 41 | 42 | class LookupModule(LookupBase): 43 | 44 | def run(self, terms, variables=None, **kwargs): 45 | 46 | ret = [] 47 | for term in terms: 48 | display.debug("File lookup term: %s" % term) 49 | 50 | lookupfile = self.find_file_in_search_path(variables, 'files', term) 51 | 52 | display.vvvv(u"File lookup using %s as file" % lookupfile) 53 | try: 54 | if lookupfile: 55 | contents, show_data = self._loader._get_file_contents(lookupfile) 56 | ret.append(contents.rstrip()[0]) 57 | else: 58 | raise AnsibleParserError() 59 | except AnsibleParserError: 60 | raise AnsibleError("could not locate file in lookup: %s" % term) 61 | 62 | return ret 63 | -------------------------------------------------------------------------------- /Chapter 6/lookup_plugins/firstchar.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Practical-Ansible-2/cd6c4532f4d238bd67a34a8d14081de6feea9c00/Chapter 6/lookup_plugins/firstchar.pyc -------------------------------------------------------------------------------- /Chapter 6/myplugin.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate our custom filter 3 | hosts: frontends 4 | gather_facts: false 5 | vars: 6 | statement: "Puppet is an excellent automation tool!" 7 | 8 | tasks: 9 | - name: make a statement 10 | debug: 11 | msg: "{{ statement | improve_automation }}" 12 | -------------------------------------------------------------------------------- /Chapter 6/myplugin2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate our custom lookup plugin 3 | hosts: frontends 4 | gather_facts: false 5 | 6 | tasks: 7 | - name: make a statement 8 | debug: 9 | msg: "{{ lookup('firstchar', 'testdoc.txt')}}" 10 | -------------------------------------------------------------------------------- /Chapter 6/pipetest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: frontends 3 | tasks: 4 | - debug: 5 | msg: "{{lookup('pipe', '/usr/bin/whoami')}}" 6 | -------------------------------------------------------------------------------- /Chapter 6/testdoc.txt: -------------------------------------------------------------------------------- 1 | Hello 2 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/filter_plugins/custom_filter.py: -------------------------------------------------------------------------------- 1 | # (c) 2020, James Freeman 2 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 3 | def improve_automation(a): 4 | return a.replace("Puppet", "Ansible") 5 | class FilterModule(object): 6 | '''improve_automation filters''' 7 | def filters(self): 8 | return {'improve_automation': improve_automation} 9 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/filter_plugins/custom_filter.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Practical-Ansible-2/cd6c4532f4d238bd67a34a8d14081de6feea9c00/Chapter 7/best-practise-directory-structure/filter_plugins/custom_filter.pyc -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/inventories/development/group_vars/app.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8080 3 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/inventories/development/hosts: -------------------------------------------------------------------------------- 1 | [app] 2 | app01.dev.example.com 3 | app02.dev.example.com 4 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/inventories/production/group_vars/app.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 80 3 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/inventories/production/hosts: -------------------------------------------------------------------------------- 1 | [app] 2 | app01.prod.example.com 3 | app02.prod.example.com 4 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/library/remote_filecopy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # 3 | import shutil 4 | 5 | # Copyright: (c) 2018, Jesse Keating 6 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 7 | 8 | ANSIBLE_METADATA = {'metadata_version': '1.1', 9 | 'status': ['preview'], 10 | 'supported_by': 'community'} 11 | 12 | DOCUMENTATION = ''' 13 | --- 14 | module: remote_filecopy 15 | version_added: "2.9" 16 | short_description: Copy a file on the remote host 17 | description: 18 | - The remote_copy module copies a file on the remote host from a given source to a provided destination. 19 | options: 20 | source: 21 | description: 22 | - Path to a file on the source file on the remote host 23 | required: True 24 | dest: 25 | description: 26 | - Path to the destination on the remote host for the copy 27 | required: True 28 | author: 29 | - Jesse Keating 30 | ''' 31 | EXAMPLES = ''' 32 | # Example from Ansible Playbooks 33 | - name: backup a config file 34 | remote_copy: 35 | source: /etc/herp/derp.conf 36 | dest: /root/herp-derp.conf.bak 37 | ''' 38 | RETURN = ''' 39 | source: 40 | description: source file used for the copy 41 | returned: success 42 | type: string 43 | sample: "/path/to/file.name" 44 | dest: 45 | description: destination of the copy 46 | returned: success 47 | type: string 48 | sample: "/path/to/destination.file" 49 | gid: 50 | description: group ID of destination target 51 | returned: success 52 | type: int 53 | sample: 502 54 | group: 55 | description: group name of destination target 56 | returned: success 57 | type: string 58 | sample: "users" 59 | uid: 60 | description: owner ID of destination target 61 | returned: success 62 | type: int 63 | sample: 502 64 | owner: 65 | description: owner name of destination target 66 | returned: success 67 | type: string 68 | sample: "fred" 69 | mode: 70 | description: permissions of the destination target 71 | returned: success 72 | type: int 73 | sample: 0644 74 | size: 75 | description: size of destination target 76 | returned: success 77 | type: int 78 | sample: 20 79 | state: 80 | description: state of destination target 81 | returned: success 82 | type: string 83 | sample: "file" 84 | ''' 85 | 86 | def main(): 87 | module = AnsibleModule( 88 | argument_spec = dict( 89 | source=dict(required=True, type='str'), 90 | dest=dict(required=True, type='str') 91 | ), 92 | ) 93 | shutil.copy(module.params['source'], 94 | module.params['dest']) 95 | 96 | module.exit_json(changed=True) 97 | 98 | from ansible.module_utils.basic import * 99 | if __name__ == '__main__': 100 | main() 101 | 102 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/roles/installapp/.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/ -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/roles/installapp/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 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/roles/installapp/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for installapp -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/roles/installapp/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for installapp -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/roles/installapp/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 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/roles/installapp/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Display http_port variable contents 3 | debug: 4 | var: http_port 5 | 6 | - name: Create /tmp/foo 7 | file: 8 | path: /tmp/foo 9 | state: file 10 | 11 | - name: Use custom module to copy /tmp/foo 12 | remote_filecopy: 13 | source: /tmp/foo 14 | dest: /tmp/bar 15 | 16 | - name: Define a fact about automation 17 | set_fact: 18 | about_automation: "Puppet is an excellent automation tool" 19 | 20 | - name: Tell us about automation with a custom filter applied 21 | debug: 22 | msg: "{{ about_automation | improve_automation }}" 23 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/roles/installapp/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | 3 | -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/roles/installapp/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - installapp -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/roles/installapp/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for installapp -------------------------------------------------------------------------------- /Chapter 7/best-practise-directory-structure/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play using best practise directory structure 3 | hosts: all 4 | 5 | roles: 6 | - installapp 7 | -------------------------------------------------------------------------------- /Chapter 7/hosts: -------------------------------------------------------------------------------- 1 | [app] 2 | app01.dev.example.com 3 | app02.dev.example.com 4 | -------------------------------------------------------------------------------- /Chapter 7/osvariants.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate group_by module 3 | hosts: all 4 | 5 | tasks: 6 | - name: Create inventory groups based on host facts 7 | group_by: 8 | key: os_{{ ansible_facts['distribution'] }} 9 | 10 | - name: Play to install Apache on CentOS 11 | hosts: os_CentOS 12 | become: true 13 | 14 | tasks: 15 | - name: Install Apache on CentOS 16 | yum: 17 | name: httpd 18 | state: present 19 | 20 | - name: Play to install Apache on Ubuntu 21 | hosts: os_Ubuntu 22 | become: true 23 | 24 | tasks: 25 | - name: Install Apache on Ubuntu 26 | apt: 27 | name: apache2 28 | state: present 29 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-1/inventories/development/group_vars/all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8080 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-1/inventories/development/hosts: -------------------------------------------------------------------------------- 1 | [app] 2 | app01.dev.example.com 3 | app02.dev.example.com 4 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-1/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play using best practise directory structure 3 | hosts: all 4 | 5 | tasks: 6 | - name: Display the value of our inventory variable 7 | debug: 8 | var: http_port 9 | 10 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-2/inventories/development/group_vars/all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8080 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-2/inventories/development/group_vars/app.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8081 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-2/inventories/development/hosts: -------------------------------------------------------------------------------- 1 | [app] 2 | app01.dev.example.com 3 | app02.dev.example.com 4 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-2/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play using best practise directory structure 3 | hosts: all 4 | 5 | tasks: 6 | - name: Display the value of our inventory variable 7 | debug: 8 | var: http_port 9 | 10 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-3/inventories/development/group_vars/all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8080 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-3/inventories/development/group_vars/centos.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8082 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-3/inventories/development/group_vars/dapp.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8081 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-3/inventories/development/group_vars/newcentos.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8083 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-3/inventories/development/hosts: -------------------------------------------------------------------------------- 1 | [app] 2 | app01.dev.example.com 3 | app02.dev.example.com 4 | 5 | [centos:children] 6 | app 7 | 8 | [newcentos:children] 9 | app 10 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-3/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play using best practise directory structure 3 | hosts: all 4 | 5 | tasks: 6 | - name: Display the value of our inventory variable 7 | debug: 8 | var: http_port 9 | 10 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-4/inventories/development/group_vars/all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8080 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-4/inventories/development/group_vars/centos.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8082 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-4/inventories/development/group_vars/dapp.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8081 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-4/inventories/development/group_vars/newcentos.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 8083 3 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-4/inventories/development/host_vars/app01.dev.example.com.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_port: 9090 3 | 4 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-4/inventories/development/hosts: -------------------------------------------------------------------------------- 1 | [app] 2 | app01.dev.example.com 3 | app02.dev.example.com 4 | 5 | [centos:children] 6 | app 7 | 8 | [newcentos:children] 9 | app 10 | -------------------------------------------------------------------------------- /Chapter 7/variable-precedence-4/site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play using best practise directory structure 3 | hosts: all 4 | 5 | tasks: 6 | - name: Display the value of our inventory variable 7 | debug: 8 | var: http_port 9 | 10 | -------------------------------------------------------------------------------- /Chapter 8/add_to_loadbalancer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo Adding $1 to load balancer... 3 | -------------------------------------------------------------------------------- /Chapter 8/async.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate asynchronous tasks 3 | hosts: frontends 4 | become: true 5 | 6 | tasks: 7 | - name: A simulated long running task 8 | shell: "sleep 20" 9 | async: 30 10 | poll: 5 11 | 12 | -------------------------------------------------------------------------------- /Chapter 8/async2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate asynchronous tasks 3 | hosts: frontends 4 | become: true 5 | 6 | tasks: 7 | - name: A simulated long running task 8 | shell: "sleep 20" 9 | async: 30 10 | poll: 0 11 | register: long_task 12 | 13 | - name: Check on the asynchronous task 14 | async_status: 15 | jid: "{{ long_task.ansible_job_id }}" 16 | register: async_result 17 | until: async_result.finished 18 | retries: 30 19 | 20 | -------------------------------------------------------------------------------- /Chapter 8/delegate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate task delegation 3 | hosts: frontends 4 | 5 | tasks: 6 | - name: Remove host from the load balancer 7 | command: ./remove_from_loadbalancer.sh {{ inventory_hostname }} 8 | args: 9 | chdir: "{{ playbook_dir }}" 10 | delegate_to: localhost 11 | 12 | - name: Deploy code to host 13 | debug: 14 | msg: Deployment code would go here.... 15 | 16 | - name: Add host back to the load balancer 17 | command: ./add_to_loadbalancer.sh {{ inventory_hostname }} 18 | args: 19 | chdir: "{{ playbook_dir }}" 20 | delegate_to: localhost 21 | -------------------------------------------------------------------------------- /Chapter 8/delegate2.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Second task delegation example 3 | hosts: frontends 4 | 5 | tasks: 6 | - name: Perform an rsync from localhost to inventory hosts 7 | local_action: command rsync -a /tmp/ {{ inventory_hostname }}:/tmp/target/ 8 | -------------------------------------------------------------------------------- /Chapter 8/hosts: -------------------------------------------------------------------------------- 1 | [frontends] 2 | frt01.example.com 3 | frt02.example.com 4 | -------------------------------------------------------------------------------- /Chapter 8/inlinevaultplaybook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: A play that makes use of an Ansible Vault 3 | hosts: frontends 4 | 5 | vars: 6 | secretdata: !vault | 7 | $ANSIBLE_VAULT;1.1;AES256 8 | 34393431303339353735656236656130336664666337363732376262343837663738393465623930 9 | 3366623061306364643966666565316235313136633264310a623736643362663035373861343435 10 | 62346264313638656363323835323833633264636561366339326332356430383734653030306637 11 | 3736336533656230380a316364313831666463643534633530393337346164356634613065396434 12 | 33316338336266636666353334643865363830346566666331303763643564323065 13 | 14 | tasks: 15 | - name: Tell me a secret 16 | debug: 17 | msg: "Your secret data is: {{ secretdata }}" 18 | -------------------------------------------------------------------------------- /Chapter 8/localhosts: -------------------------------------------------------------------------------- 1 | [local] 2 | localhost 3 | 4 | -------------------------------------------------------------------------------- /Chapter 8/localhosts2: -------------------------------------------------------------------------------- 1 | [local] 2 | frt01.example.com ansible_connection=local 3 | 4 | -------------------------------------------------------------------------------- /Chapter 8/maxfail.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: A simple play to demonstrate use of max_fail_percentage 3 | hosts: frontends 4 | gather_facts: no 5 | serial: 5 6 | max_fail_percentage: 50 7 | 8 | tasks: 9 | - name: A task that will sometimes fail 10 | debug: 11 | msg: This might fail 12 | failed_when: inventory_hostname in ansible_play_batch[0:3] 13 | - name: A task that will succeed 14 | debug: 15 | msg: Success! 16 | -------------------------------------------------------------------------------- /Chapter 8/morehosts: -------------------------------------------------------------------------------- 1 | [frontends] 2 | frt[01:10].example.com 3 | -------------------------------------------------------------------------------- /Chapter 8/prompt.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: A simple play to demonstrate prompting in a playbook 3 | hosts: frontends 4 | 5 | vars_prompt: 6 | - name: loginid 7 | prompt: "Enter your username" 8 | private: no 9 | - name: password 10 | prompt: "Enter your password" 11 | private: yes 12 | 13 | tasks: 14 | - name: Proceed with login 15 | debug: 16 | msg: "Logging in as {{ loginid }}..." 17 | -------------------------------------------------------------------------------- /Chapter 8/remove_from_loadbalancer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo Removing $1 from load balancer... 3 | -------------------------------------------------------------------------------- /Chapter 8/runonce.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Play to demonstrate the run_once directive 3 | hosts: frontends 4 | serial: 5 5 | 6 | tasks: 7 | - name: Upgrade database schema 8 | debug: 9 | msg: Upgrading database schema... 10 | run_once: true 11 | -------------------------------------------------------------------------------- /Chapter 8/secret.yml: -------------------------------------------------------------------------------- 1 | $ANSIBLE_VAULT;1.1;AES256 2 | 63333734623764633865633237333166333634353334373862346334643631303163653931306138 3 | 6334356465396463643936323163323132373836336461370a343236386266313331653964326334 4 | 62363737663165336539633262366636383364343663396335643635623463626336643732613830 5 | 6139363035373736370a646661396464386364653935636366633663623261633538626230616630 6 | 35346465346430636463323838613037386636333334356265623964633763333532366561323266 7 | 3664613662643263383464643734633632383138363663323730 8 | -------------------------------------------------------------------------------- /Chapter 8/serial.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simple serial demonstration play 3 | hosts: frontends 4 | serial: 1 5 | gather_facts: false 6 | 7 | tasks: 8 | - name: First task 9 | command: date 10 | - name: Second task 11 | command: date 12 | -------------------------------------------------------------------------------- /Chapter 8/switches: -------------------------------------------------------------------------------- 1 | [switches] 2 | cmls01.example.com 3 | cmls02.example.com 4 | 5 | [switches:vars] 6 | ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p -q bastion.example.com"' 7 | -------------------------------------------------------------------------------- /Chapter 8/tags.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simple play to demonstrate use of tags 3 | hosts: frontends 4 | 5 | tasks: 6 | - name: Install nginx 7 | yum: 8 | name: nginx 9 | state: present 10 | tags: 11 | - install 12 | 13 | - name: Install nginx configuration from template 14 | template: 15 | src: templates/nginx.conf.j2 16 | dest: /etc/nginx.conf 17 | tags: 18 | - customize 19 | -------------------------------------------------------------------------------- /Chapter 8/templates/nginx.conf.j2: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes auto; 3 | error_log /var/log/nginx/error.log; 4 | pid /run/nginx.pid; 5 | 6 | include /usr/share/nginx/modules/*.conf; 7 | 8 | events { 9 | worker_connections 1024; 10 | } 11 | 12 | http { 13 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 14 | '$status $body_bytes_sent "$http_referer" ' 15 | '"$http_user_agent" "$http_x_forwarded_for"'; 16 | 17 | access_log /var/log/nginx/access.log main; 18 | 19 | sendfile on; 20 | tcp_nopush on; 21 | tcp_nodelay on; 22 | keepalive_timeout 65; 23 | types_hash_max_size 2048; 24 | 25 | include /etc/nginx/mime.types; 26 | default_type application/octet-stream; 27 | 28 | # Load modular configuration files from the /etc/nginx/conf.d directory. 29 | # See http://nginx.org/en/docs/ngx_core_module.html#include 30 | # for more information. 31 | include /etc/nginx/conf.d/*.conf; 32 | 33 | server { 34 | listen 80 default_server; 35 | listen [::]:80 default_server; 36 | server_name _; 37 | root /usr/share/nginx/html; 38 | 39 | # Load configuration files for the default server block. 40 | include /etc/nginx/default.d/*.conf; 41 | 42 | location / { 43 | } 44 | 45 | error_page 404 /404.html; 46 | location = /40x.html { 47 | } 48 | 49 | error_page 500 502 503 504 /50x.html; 50 | location = /50x.html { 51 | } 52 | } 53 | 54 | 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Chapter 8/vaultplaybook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: A play that makes use of an Ansible Vault 3 | hosts: frontends 4 | 5 | vars_files: 6 | - secret.yml 7 | 8 | tasks: 9 | - name: Tell me a secret 10 | debug: 11 | msg: "Your secret data is: {{ secretdata }}" 12 | -------------------------------------------------------------------------------- /Chapter 9/conditional-example/group_vars/cumulusvx.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ansible_user: cumulus 3 | become: false 4 | -------------------------------------------------------------------------------- /Chapter 9/conditional-example/hosts: -------------------------------------------------------------------------------- 1 | [cumulusvx] 2 | vx01.example.com 3 | 4 | -------------------------------------------------------------------------------- /Chapter 9/conditional-example/portenable.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simple play to demonstrate conditional on Cumulus Linux 3 | hosts: cumulusvx 4 | 5 | tasks: 6 | - name: Enable swp2 if it is disabled 7 | nclu: 8 | commands: 9 | - add int swp2 10 | commit: yes 11 | when: ansible_swp2.active == false 12 | -------------------------------------------------------------------------------- /Chapter 9/connection-example/cumulusvx_facts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Simply play to gather Cumulus VX switch facts 3 | hosts: cumulusvx 4 | gather_facts: no 5 | 6 | tasks: 7 | - name: Gather facts 8 | setup: 9 | gather_subset: all 10 | -------------------------------------------------------------------------------- /Chapter 9/connection-example/group_vars/cumulusvx.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ansible_user: cumulus 3 | become: false 4 | -------------------------------------------------------------------------------- /Chapter 9/connection-example/group_vars/routers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ansible_connection: network_cli 3 | ansible_network_os: ios 4 | ansible_become: True 5 | ansible_become_method: enable 6 | -------------------------------------------------------------------------------- /Chapter 9/connection-example/hosts: -------------------------------------------------------------------------------- 1 | [routers] 2 | n1.example.com 3 | n2.example.com 4 | 5 | [cumulusvx] 6 | vx01.example.com 7 | -------------------------------------------------------------------------------- /Chapter 9/connection-example/ios_facts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: routers 3 | gather_facts: False 4 | tasks: 5 | - name: Gather IOS facts 6 | ios_facts: 7 | gather_subset: all 8 | -------------------------------------------------------------------------------- /Chapter 9/environment-example/group_vars/bastion_cumulusvx.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ansible_user: cumulus 3 | ansible_become: false 4 | ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q bastion.example.com"' 5 | proxy_env: 6 | http_proxy: http://proxy.example.com:8080 7 | -------------------------------------------------------------------------------- /Chapter 9/environment-example/group_vars/bastion_routers.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ansible_connection: network_cli 3 | ansible_network_os: ios 4 | ansible_become: True 5 | ansible_become_method: enable 6 | ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q bastion.example.com"' 7 | proxy_env: 8 | http_proxy: http://proxy.example.com:8080 9 | -------------------------------------------------------------------------------- /Chapter 9/environment-example/hosts: -------------------------------------------------------------------------------- 1 | [bastion_routers] 2 | n1.example.com 3 | n2.example.com 4 | 5 | [bastion_cumulusvx] 6 | vx01.example.com 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Practical Ansible 2 5 | 6 | Practical Ansible 2 7 | 8 | This is the code repository for [Practical Ansible 2](https://www.packtpub.com/cloud-networking/practical-ansible-2?utm_source=github&utm_medium=repository&utm_campaign=9781789807462), published by Packt. 9 | 10 | **Automate infrastructure, manage configuration, and deploy applications with Ansible 2.9** 11 | 12 | ## What is this book about? 13 | Ansible enables you to automate software provisioning, configuration management, and application roll-outs, and can be used as a deployment and orchestration tool. While Ansible provides simple yet powerful features to automate multi-layer environments using agentless communication, it can also solve other critical IT challenges, such as ensuring continuous integration and continuous deployment (CI/CD) with zero downtime. 14 | In this book, you'll work with Ansible 2.9 and learn to solve complex issues quickly with the help of task-oriented scenarios. You'll start by installing and configuring Ansible on Linux and macOS to automate monotonous and repetitive IT tasks and get to grips with concepts such as playbooks, inventories, and network modules. As you progress, you'll gain insight into the YAML syntax and learn how to port between Ansible versions. In addition to this, you'll also understand how Ansible enables you to orchestrate multi-layer environments such as networks, containers, and the cloud. 15 | 16 | This book covers the following exciting features: 17 | * Become familiar with the fundamentals of the Ansible framework 18 | * Set up role-based variables and dependencies 19 | * Avoid common mistakes and pitfalls when creating modules from scratch 20 | * Encourage upstream contributions by submitting the plugins to Ansible 21 | * Build best practices to create inventory files for cloud environments 22 | 23 | 24 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1789807468) today! 25 | 26 | https://www.packtpub.com/ 27 | 28 | ## Instructions and Navigations 29 | All of the code is organized into folders. For example, Chapter02. 30 | 31 | The code will look like the following: 32 | ``` 33 | if (test expression) 34 | { 35 | Statement upon condition is true 36 | } 37 | ``` 38 | 39 | **Following is what you need for this book:** 40 | If you are a DevOps engineer, administrator, or any IT professional looking to automate IT tasks using Ansible, this book is for you. Prior knowledge of Ansible is not necessary. 41 | 42 | With the following software and hardware list you can run all code files present in the book (Chapter 1-12). 43 | 44 | ### Software and Hardware List 45 | 46 | | Chapter | Software required | OS required | 47 | | -------- | --------------------------------------------------------| --------------------------------| 48 | | 1-12 | At least one Linux server (virtual machine or physical) | CentOS 7 or Ubuntu Server 18.04 | 49 | | 1-12 | Ansible 2.9 | CentOS 7 or Ubuntu Server 18.04 | 50 | | 1-12 | AWX release 10.0.0 or later | CentOS 7 or Ubuntu Server 18.04 | 51 | 52 | 53 | 54 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://static.packt-cdn.com/downloads/9781789807462_ColorImages.pdf). 55 | 56 | ### Related products 57 | * Mastering Ansible - Third Edition [[Packt]](https://www.packtpub.com/virtualization-and-cloud/mastering-ansible-third-edition?utm_source=github&utm_medium=repository&utm_campaign=9781789951547) [[Amazon]](https://www.amazon.com/dp/1789951542) 58 | 59 | * Learning Ansible 2.7 - Third Edition [[Packt]](https://www.packtpub.com/networking-and-servers/learning-ansible-27-third-edition?utm_source=github&utm_medium=repository&utm_campaign=9781789954333) [[Amazon]](https://www.amazon.com/dp/1789954339) 60 | 61 | ## Get to Know the Authors 62 | **Daniel Oh** 63 | Daniel Oh is a principal technical marketing manager at Red Hat. He provides runtimes, frameworks, fast data access, and high-performance messaging in flexible, easy-to-use, cost-effective, open, and collaborative ways. He's also a CNCF ambassador and DevOps Institute ambassador who evangelizes how to design and develop cloud-native serverless microservices and deploy them to multi/hybrid cloud-native platforms based on CNCF projects. Daniel loves to share his developer experiences with DevOps folks in terms of how to evolve traditional microservices to cloud-native, event-driven, and serverless applications via technical workshops, brown bag sessions, hackathons, and hands-on labs across regions at many international conferences. 64 | 65 | **James Freeman** 66 | James Freeman is an accomplished IT consultant with over 20 years' experience in the technology industry. He has more than 5 years of first-hand experience of solving real-world enterprise problems in production environments using Ansible, frequently introducing Ansible as a new technology to businesses and CTOs for the first time. In addition, he has authored and facilitated bespoke Ansible workshops and training sessions, and has presented at both international conferences and meetups on Ansible. 67 | 68 | **Fabio Alessandro Locati** 69 | Fabio Alessandro Locati – commonly known as Fale – is an EMEA senior solution architect at Red Hat, a public speaker, an author, and an open source contributor. His primary areas of expertise are Linux, automation, security, and cloud technologies. Fale has more than 15 years of working experience in IT, with many of them spent consulting for many companies, including dozens of Fortune 500 companies. Fale has written Learning Ansible 2.7, Learning Ansible 2, and OpenStack Cloud Security, and has been part of the review process of multiple books. 70 | 71 | 72 | ## Other books by the authors 73 | * [Hands-On Enterprise Automation on Linux]https://www.packtpub.com/business-other/hands-on-enterprise-automation-on-linux?utm_source=github&utm_medium=repository&utm_campaign=9781789131611) 74 | 75 | 76 | ### Suggestions and Feedback 77 | [Click here](https://docs.google.com/forms/d/e/1FAIpQLSdy7dATC6QmEL81FIUuymZ0Wy9vH1jHkvpY57OiMeKGqib_Ow/viewform) if you have any feedback or suggestions. 78 | ### Download a free PDF 79 | 80 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
81 |

https://packt.link/free-ebook/9781789807462

--------------------------------------------------------------------------------