This is in continuation of the articles of the series “Learning Ansible”. So, in this article, we will be doing lots of things; be patient and keep learning.
The list of topics which we will be covering is as below.
- How to create your own local ansible config file.
- Playbook Introduction and writing your first playbook.
- Ansible setup module and fact variables.
So, let’s get started quickly.
How to create your own local Ansible config file
In the previous article
Getting started with Ansible – Part 3, we have learned about the Ansible configuration. So here, we are going to see how you can set up your own local Ansible config. This local config should be present in the same directory where our inventory file is present.
Let’s create local config with the below command.
vim ansible.cfg
Now, add the below configuration which is similar to what we saw in the global Ansible configuration file previously.
- [defaults]
- host_key_checking = False
- inventory = invent
- timeout = 15
- log_path = /var/log/ansible.log
-
- [privilege_escalation]
- become = True
- become_method = sudo
- become_user = root
- become_ask_pass = False
Note
Here, we have renamed our inventory file from inventory to invent using the below command.
Now, as we have given log_path for the Ansible log but we don’t have that file created.
So, we are going to create the Ansible.log file and will change the ownership for Ubuntu user with the below commands, so that the logs can be added to this file.
- sudo touch /var/log/ansible.log
- sudo chown ubuntu:ubuntu /var/log/ansible.log
TIP
As we have defined the inventory file inside the local Ansible config, so now we can execute ping on all the servers without giving the inventory path as opposed to earlier when we had to pass the inventory file.
So, the shortened new command will look like below.
OUTPUT
We can see that ping has executed successfully on all servers. Now, let’s do one more thing and install one more service called NTP on all servers using Ansible package module.
The below command will install NTP service on all the servers without giving –become command as we have defined all this configuration in our local ansible.config.
- ansible -m package -a "name=ntp state=present" all
Great! So, by now, we have seen how we can define the configurations locally and run the Ansible modules with ease.
As we have created a log file, we can also see the log file using the below command to check if logs have been generated or not.
OUTPUT
We can see that logs are being registered properly inside the log file, i.e., we are good.
As everyone wants to simplify their work as much as possible, so with Ansible, we have something called Playbooks. So, let’s see what they are.
Introduction to Playbook and writing your first Playbook
Playbooks are the files where the Ansible code is written. Playbooks are written in YAML format. YAML stands for Yet Another Markup Language. Playbooks are one of the core features of Ansible and tell Ansible what to execute. They are like a to-do list for Ansible that contains a list of tasks.
Playbooks are a completely different way to use Ansible than in ad-hoc task execution mode and thus are particularly powerful.
That was enough for the introduction, let’s do some practical stuff and write our first Playbook.
Under our project named “superman”, I have created a folder named playbook exercise and we are going to create a file named web.yml which is the name of the playbook with the below command.
Then add the below code inside web.yml file. (yml is the extension for YAML file)
- -- - -hosts: WebServersGroup
- become: yes
- tasks: -name: Install httpd service
- yum: name: httpd
- state: present - name: Start and Enable httpd service
- service: name: httpd
- state: started
- enabled: yes
Let’s understand what it is doing
So above in this playbook we have one play (play starts with -hosts). This is going to install apache service on all the webservers as we have given the web servers group in hosts and then will start and enable the service on all web servers. So it contains 2 tasks.
- Playbooks are pretty much self-explanatory.
- To execute playbook, we use the below command
OUTPUT
We can see from the output that service has been installed on web server 01 and 02 but failed in webserver 03.
NOTE
Package could not be installed on web server 03 as web server 03 is an Ubuntu machine. Also, the package name is different for Ubuntu its apache2 not httpd. Ubuntu doesn’t have yum package as well, so we have to identify the type of OS and then take the decision accordingly.
Now to take a decision, we have something called Fact Variables. So, Let’s understand them now.
Ansible setup module and fact variables
In the above screenshot, we can see the default task is being executed for all the web servers and that task is called Gathering Facts.
Gathering facts is a default task and it generates fact variables. Before ansible executes any task on the target machine it executes a module called setup module and this module collects all information about the target machine.
We can also run the setup module directly on any server. Suppose for web server 01 we can run the setup module with the below command,
- ansible -m setup websrv01
OUTPUT
- websrv01 | SUCCESS => {
- "ansible_facts": {
- "ansible_all_ipv4_addresses": ["172.31.4.33"],
- "ansible_all_ipv6_addresses": ["fe80::4a3:7ff:fe92:2f07"],
- "ansible_apparmor": {
- "status": "disabled"
- },
- "ansible_architecture": "x86_64",
- "ansible_bios_date": "08/24/2006",
- "ansible_bios_version": "4.2.amazon",
- "ansible_cmdline": {
- "BOOT_IMAGE": "/boot/vmlinuz-3.10.0-957.1.3.el7.x86_64",
- "LANG": "en_US.UTF-8",
- "console": "ttyS0,115200",
- "crashkernel": "auto",
- "ro": true,
- "root": "UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d"
- },
- "ansible_date_time": {
- "date": "2019-08-13",
- "day": "13",
- "epoch": "1565705464",
- "hour": "14",
- "iso8601": "2019-08-13T14:11:04Z",
- "iso8601_basic": "20190813T141104765176",
- "iso8601_basic_short": "20190813T141104",
- "iso8601_micro": "2019-08-13T14:11:04.765269Z",
- "minute": "11",
- "month": "08",
- "second": "04",
- "time": "14:11:04",
- "tz": "UTC",
- "tz_offset": "+0000",
- "weekday": "Tuesday",
- "weekday_number": "2",
- "weeknumber": "32",
- "year": "2019"
- },
- "ansible_default_ipv4": {
- "address": "172.31.4.33",
- "alias": "eth0",
- "broadcast": "172.31.15.255",
- "gateway": "172.31.0.1",
- "interface": "eth0",
- "macaddress": "06:a3:07:92:2f:07",
- "mtu": 9001,
- "netmask": "255.255.240.0",
- "network": "172.31.0.0",
- "type": "ether"
- },
- "ansible_default_ipv6": {},
- "ansible_device_links": {
- "ids": {},
- "labels": {},
- "masters": {},
- "uuids": {
- "xvda1": ["f41e390f-835b-4223-a9bb-9b45984ddf8d"]
- }
- },
- "ansible_devices": {
- "xvda": {
- "holders": [],
- "host": "",
- "links": {
- "ids": [],
- "labels": [],
- "masters": [],
- "uuids": []
- },
- "model": null,
- "partitions": {
- "xvda1": {
- "holders": [],
- "links": {
- "ids": [],
- "labels": [],
- "masters": [],
- "uuids": ["f41e390f-835b-4223-a9bb-9b45984ddf8d"]
- },
- "sectors": "16775168",
- "sectorsize": 512,
- "size": "8.00 GB",
- "start": "2048",
- "uuid": "f41e390f-835b-4223-a9bb-9b45984ddf8d"
- }
- },
- "removable": "0",
- "rotational": "0",
- "sas_address": null,
- "sas_device_handle": null,
- "scheduler_mode": "deadline",
- "sectors": "16777216",
- "sectorsize": "512",
- "size": "8.00 GB",
- "support_discard": "0",
- "vendor": null,
- "virtual": 1
- }
- },
- "ansible_distribution": "CentOS",
- "ansible_distribution_file_parsed": true,
- "ansible_distribution_file_path": "/etc/redhat-release",
- "ansible_distribution_file_variety": "RedHat",
- "ansible_distribution_major_version": "7",
- "ansible_distribution_release": "Core",
- "ansible_distribution_version": "7.6",
- "ansible_dns": {
- "nameservers": ["172.31.0.2"],
- "search": ["us-west-1.compute.internal"]
- },
- "ansible_domain": "us-west-1.compute.internal",
- "ansible_effective_group_id": 0,
- "ansible_effective_user_id": 0,
- "ansible_env": {
- "HOME": "/root",
- "LANG": "C",
- "LC_ALL": "C",
- "LC_MESSAGES": "C",
- "LOGNAME": "root",
- "LS_COLORS": "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:s
- g = 30;43: ca = 30;41: tw = 30;42: ow = 34;42: st = 37;44: ex = 01;32: * .tar = 01;31: * .tgz = 01;31: * .arc = 01;31: * .arj = 01;31: * .taz = 01;31: * .lha = 01;31: * .lz4 = 01;31: * .lzh = 01;31: * .lzma = 01;31: * .tlz = 01;31: * .txz = 01;31: * .tzo = 01;31: * .t7z = 01;31: * .zip = 01;31: * .z = 01;31: * .Z = 01;31: * .dz = 01;31: * .gz = 01;31: * .lrz = 01;31: * .lz = 01;31: * .lzo = 01;31: * .xz = 01;31: * .bz2 = 01;31: * .bz = 01;31: * .tbz = 01;31: * .tbz2 = 01;31: * .tz = 01;31: * .deb = 01;31: * .rpm = 01;31: * .jar = 01;31: * .war = 01;31: * .ear = 01;31: * .sar = 01;31: * .rar = 01;31: * .alz = 01;31: * .ace = 01;31: * .zoo = 01;31: * .cpio = 01;31: * .7 z = 01;31: * .rz = 01;31: * .cab = 01;31: * .jpg = 01;35: * .jpeg = 01;35: * .gif = 01;35: * .bmp = 01;35: * .pbm = 01;35: * .pgm = 01;35: * .ppm = 01;35: * .tga = 01;35: * .xbm = 01;35: * .xpm = 01;35: * .tif = 01;35: * .tiff = 01;35: * .png = 01;35: * .svg = 01;35: * .svgz = 01;35: * .mng = 01;35: * .pcx = 01;35: * .mov = 01;35: * .mpg = 01;35: * .mpeg = 01;35: * .m2v = 01;35: * .mkv = 01;35: * .webm = 01;35: * .ogm = 01;35: * .mp4 = 01;35: * .m4v = 01;35: * .mp4
- v = 01;35: * .vob = 01;35: * .qt = 01;35: * .nuv = 01;35: * .wmv = 01;35: * .asf = 01;35: * .rm = 01;35: * .rmvb = 01;35: * .flc = 01;35: * .avi = 01;35: * .fli = 01;35: * .flv = 01;35: * .gl = 01;35: * .dl = 01;35: * .xcf = 01;35: * .xwd = 01;35: * .yuv = 01;35: * .cgm = 01;35: * .emf = 01;35: * .axv = 01;35: * .anx = 01;35: * .ogv = 01;35: * .ogx = 01;35: * .aac = 01;36: * .au = 01;36: * .flac = 01;36: * .mid = 01;36: * .midi = 01;36: * .mka = 01;36: * .mp3 = 01;36: * .mpc = 01;36: * .ogg = 01;36: * .ra = 01;36: * .wav = 01;36: * .axa = 01;36: * .oga = 01;36: * .sp
- x = 01;36: * .xspf = 01;36: ",
- "MAIL": "/var/mail/devops",
- "PATH": "/sbin:/bin:/usr/sbin:/usr/bin",
- "PWD": "/home/devops",
- "SHELL": "/bin/bash",
- "SHLVL": "1",
- "SUDO_COMMAND": "/bin/sh -c echo BECOME-SUCCESS-uofgmphmzzbaydzazomtycditqzzedpj ; /usr/bin/python /home/devops/.ansible/tmp/ansibl
- e - tmp - 1565705463.54 - 247967255799117 / AnsiballZ_setup.py ",
- "SUDO_GID": "1001",
- "SUDO_UID": "1001",
- "SUDO_USER": "devops",
- "TERM": "xterm",
- "USER": "root",
- "USERNAME": "root",
- "XDG_SESSION_ID": "10",
- "_": "/usr/bin/python"
- },
- "ansible_eth0": {
- "active": true,
- "device": "eth0",
- "features": {
- "busy_poll": "off [fixed]",
- "fcoe_mtu": "off [fixed]",
- "generic_receive_offload": "on",
- "generic_segmentation_offload": "on",
- "highdma": "off [fixed]",
- "hw_tc_offload": "off [fixed]",
- "l2_fwd_offload": "off [fixed]",
- "large_receive_offload": "off [fixed]",
- "loopback": "off [fixed]",
- "netns_local": "off [fixed]",
- "ntuple_filters": "off [fixed]",
- "receive_hashing": "off [fixed]",
- "rx_all": "off [fixed]",
- "rx_checksumming": "on [fixed]",
- "rx_fcs": "off [fixed]",
- "rx_gro_hw": "off [fixed]",
- "rx_udp_tunnel_port_offload": "off [fixed]",
- "rx_vlan_filter": "off [fixed]",
- "rx_vlan_offload": "off [fixed]",
- "rx_vlan_stag_filter": "off [fixed]",
- "rx_vlan_stag_hw_parse": "off [fixed]",
- "scatter_gather": "on",
- "tcp_segmentation_offload": "on",
- "tx_checksum_fcoe_crc": "off [fixed]",
- "tx_checksum_ip_generic": "off [fixed]",
- "tx_checksum_ipv4": "on [fixed]",
- "tx_checksum_ipv6": "off [requested on]",
- "tx_checksum_sctp": "off [fixed]",
- "tx_checksumming": "on",
- "tx_fcoe_segmentation": "off [fixed]",
- "tx_gre_csum_segmentation": "off [fixed]",
- "tx_gre_segmentation": "off [fixed]",
- "tx_gso_partial": "off [fixed]",
- "tx_gso_robust": "on [fixed]",
- "tx_ipip_segmentation": "off [fixed]",
- "tx_lockless": "off [fixed]",
- "tx_nocache_copy": "off",
- "tx_scatter_gather": "on",
- "tx_scatter_gather_fraglist": "off [fixed]",
- "tx_sctp_segmentation": "off [fixed]",
- "tx_sit_segmentation": "off [fixed]",
- "tx_tcp6_segmentation": "off [requested on]",
- "tx_tcp_ecn_segmentation": "off [fixed]",
- "tx_tcp_mangleid_segmentation": "off",
- "tx_tcp_segmentation": "on",
- "tx_udp_tnl_csum_segmentation": "off [fixed]",
- "tx_udp_tnl_segmentation": "off [fixed]",
- "tx_vlan_offload": "off [fixed]",
- "tx_vlan_stag_hw_insert": "off [fixed]",
- "udp_fragmentation_offload": "off [fixed]",
- "vlan_challenged": "off [fixed]"
- },
- "hw_timestamp_filters": [],
- "ipv4": {
- "address": "172.31.4.33",
- "broadcast": "172.31.15.255",
- "netmask": "255.255.240.0",
- "network": "172.31.0.0"
- },
- "ipv6": [{
- "address": "fe80::4a3:7ff:fe92:2f07",
- "prefix": "64",
- "scope": "link"
- }],
- "macaddress": "06:a3:07:92:2f:07",
- "module": "xen_netfront",
- "mtu": 9001,
- "pciid": "vif-0",
- "promisc": false,
- "timestamping": ["rx_software", "software"],
- "type": "ether"
- },
- "ansible_fibre_channel_wwn": [],
- "ansible_fips": false,
- "ansible_form_factor": "Other",
- "ansible_fqdn": "ip-172-31-4-33.us-west-1.compute.internal",
- "ansible_hostname": "ip-172-31-4-33",
- "ansible_hostnqn": "",
- "ansible_interfaces": ["lo", "eth0"],
- "ansible_is_chroot": false,
- "ansible_iscsi_iqn": "",
- "ansible_kernel": "3.10.0-957.1.3.el7.x86_64",
- "ansible_lo": {
- "active": true,
- "device": "lo",
- "features": {
- "busy_poll": "off [fixed]",
- "fcoe_mtu": "off [fixed]",
- "generic_receive_offload": "on",
- "generic_segmentation_offload": "on",
- "highdma": "on [fixed]",
- "hw_tc_offload": "off [fixed]",
- "l2_fwd_offload": "off [fixed]",
- "large_receive_offload": "off [fixed]",
- "loopback": "on [fixed]",
- "netns_local": "on [fixed]",
- "ntuple_filters": "off [fixed]",
- "receive_hashing": "off [fixed]",
- "rx_all": "off [fixed]",
- "rx_checksumming": "on [fixed]",
- "rx_fcs": "off [fixed]",
- "rx_gro_hw": "off [fixed]",
- "rx_udp_tunnel_port_offload": "off [fixed]",
- "rx_vlan_filter": "off [fixed]",
- "rx_vlan_offload": "off [fixed]",
- "rx_vlan_stag_filter": "off [fixed]",
- "rx_vlan_stag_hw_parse": "off [fixed]",
- "scatter_gather": "on",
- "tcp_segmentation_offload": "on",
- "tx_checksum_fcoe_crc": "off [fixed]",
- "tx_checksum_ip_generic": "on [fixed]",
- "tx_checksum_ipv4": "off [fixed]",
- "tx_checksum_ipv6": "off [fixed]",
- "tx_checksum_sctp": "on [fixed]",
- "tx_checksumming": "on",
- "tx_fcoe_segmentation": "off [fixed]",
- "tx_gre_csum_segmentation": "off [fixed]",
- "tx_gre_segmentation": "off [fixed]",
- "tx_gso_partial": "off [fixed]",
- "tx_gso_robust": "off [fixed]",
- "tx_ipip_segmentation": "off [fixed]",
- "tx_lockless": "on [fixed]",
- "tx_nocache_copy": "off [fixed]",
- "tx_scatter_gather": "on [fixed]",
- "tx_scatter_gather_fraglist": "on [fixed]",
- "tx_sctp_segmentation": "on",
- "tx_sit_segmentation": "off [fixed]",
- "tx_tcp6_segmentation": "on",
- "tx_tcp_ecn_segmentation": "on",
- "tx_tcp_mangleid_segmentation": "on",
- "tx_tcp_segmentation": "on",
- "tx_udp_tnl_csum_segmentation": "off [fixed]",
- "tx_udp_tnl_segmentation": "off [fixed]",
- "tx_vlan_offload": "off [fixed]",
- "tx_vlan_stag_hw_insert": "off [fixed]",
- "udp_fragmentation_offload": "on",
- "vlan_challenged": "on [fixed]"
- },
- "hw_timestamp_filters": [],
- "ipv4": {
- "address": "127.0.0.1",
- "broadcast": "host",
- "netmask": "255.0.0.0",
- "network": "127.0.0.0"
- },
- "ipv6": [{
- "address": "::1",
- "prefix": "128",
- "scope": "host"
- }],
- "mtu": 65536,
- "promisc": false,
- "timestamping": ["rx_software", "software"],
- "type": "loopback"
- },
- "ansible_local": {},
- "ansible_lsb": {},
- "ansible_machine": "x86_64",
- "ansible_machine_id": "05cb8c7b39fe0f70e3ce97e5beab809d",
- "ansible_memfree_mb": 658,
- "ansible_memory_mb": {
- "nocache": {
- "free": 854,
- "used": 135
- },
- "real": {
- "free": 658,
- "total": 989,
- "used": 331
- },
- "swap": {
- "cached": 0,
- "free": 0,
- "total": 0,
- "used": 0
- }
- },
- "ansible_memtotal_mb": 989,
- "ansible_mounts": [{
- "block_available": 1814541,
- "block_size": 4096,
- "block_total": 2094336,
- "block_used": 279795,
- "device": "/dev/xvda1",
- "fstype": "xfs",
- "inode_available": 4167224,
- "inode_total": 4193792,
- "inode_used": 26568,
- "mount": "/",
- "options": "rw,seclabel,relatime,attr2,inode64,noquota",
- "size_available": 7432359936,
- "size_total": 8578400256,
- "uuid": "f41e390f-835b-4223-a9bb-9b45984ddf8d"
- }],
- "ansible_nodename": "ip-172-31-4-33.us-west-1.compute.internal",
- "ansible_os_family": "RedHat",
- "ansible_pkg_mgr": "yum",
- "ansible_proc_cmdline": {
- "BOOT_IMAGE": "/boot/vmlinuz-3.10.0-957.1.3.el7.x86_64",
- "LANG": "en_US.UTF-8",
- "console": ["tty0", "ttyS0,115200n8", "ttyS0,115200"],
- "crashkernel": "auto",
- "ro": true,
- "root": "UUID=f41e390f-835b-4223-a9bb-9b45984ddf8d"
- },
- "ansible_processor": ["0", "GenuineIntel", "Intel(R) Xeon(R) CPU E5-2676 v3 @ 2.40GHz"],
- "ansible_processor_cores": 1,
- "ansible_processor_count": 1,
- "ansible_processor_threads_per_core": 1,
- "ansible_processor_vcpus": 1,
- "ansible_product_name": "HVM domU",
- "ansible_product_serial": "ec2627bf-8996-84cc-d65d-a54b5642cab9",
- "ansible_product_uuid": "EC2627BF-8996-84CC-D65D-A54B5642CAB9",
- "ansible_product_version": "4.2.amazon",
- "ansible_python": {
- "executable": "/usr/bin/python",
- "has_sslcontext": true,
- "type": "CPython",
- "version": {
- "major": 2,
- "micro": 5,
- "minor": 7,
- "releaselevel": "final",
- "serial": 0
- },
- "version_info": [
- 2,
- 7,
- 5, "final",
- 0
- ]
- },
- "ansible_python_version": "2.7.5",
- "ansible_real_group_id": 0,
- "ansible_real_user_id": 0,
- "ansible_selinux": {
- "config_mode": "enforcing",
- "mode": "enforcing",
- "policyvers": 31,
- "status": "enabled",
- "type": "targeted"
- },
- "ansible_selinux_python_present": true,
- "ansible_service_mgr": "systemd",
- "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOklEtADmwCE2vj32jD1W8gy9cvd0cIBhxw06GFeZ5R1v
- CDGXZ5xw + bjk3jjjoOSgOiORZKh2zOTMjZdruCbQmI = ",
- "ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIN9z16imlEAENHPoLAlK4x2XwolWs6GSCMnQ/IefmiW0",
- "ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQCYNMsV/GkMA0LQWBOI7Ng0OW24tPXGGA2B3MTZbWiXIBGtv8tsqnWFnOIt8al0zeUJmkM
- iDkV1ATVEJK5mhyJAKWXFUZl1nqD7W9 / nT60bHbqY / HIMgtqeZJquFNe3pyxZuAWBg9paTpJjBBGYU8NrL0a5c8LHL5YP + wLnBWqJo5evekfg6aYlJQ47OLJuecZEGKK0kwnXCX0tIQ1RTH
- W0NnwBlLLqjrBy2eXKsK58rCPo4Raihcn0x5aQm8TMcICTAiW1sNnIilwKVTDgJMJMTgB9vYeTc0bwn / 4 zmTF + OWlM1X + piT / SORgirCJh9Qp94a75Puy1kL8878SwSuTB ",
- "ansible_swapfree_mb": 0,
- "ansible_swaptotal_mb": 0,
- "ansible_system": "Linux",
- "ansible_system_capabilities": ["cap_chown", "cap_dac_override", "cap_dac_read_search", "cap_fowner", "cap_fsetid", "cap_kill", "cap_setgid", "cap_setuid", "cap_setpcap", "cap_linux_immutable", "cap_net_bind_service", "cap_net_broadcast", "cap_net_admin", "cap_net_raw", "cap_ipc_lock", "cap_ipc_owner", "cap_sys_module", "cap_sys_rawio", "cap_sys_chroot", "cap_sys_ptrace", "cap_sys_pacct", "cap_sys_admin", "cap_sys_boot", "cap_sys_nice", "cap_sys_resource", "cap_sys_time", "cap_sys_tty_config", "cap_mknod", "cap_lease", "cap_audit_write", "cap_audit_control", "cap_setfcap", "cap_mac_override", "cap_mac_admin", "cap_syslog", "35", "36+ep"],
- "ansible_system_capabilities_enforced": "True",
- "ansible_system_vendor": "Xen",
- "ansible_uptime_seconds": 4414,
- "ansible_user_dir": "/root",
- "ansible_user_gecos": "root",
- "ansible_user_gid": 0,
- "ansible_user_id": "root",
- "ansible_user_shell": "/bin/bash",
- "ansible_user_uid": 0,
- "ansible_userspace_architecture": "x86_64",
- "ansible_userspace_bits": "64",
- "ansible_virtualization_role": "guest",
- "ansible_virtualization_type": "xen",
- "discovered_interpreter_python": "/usr/bin/python",
- "gather_subset": ["all"],
- "module_setup": true
- },
- "changed": false
- }
We can see that it generates a json output with all the variables that contains lots of information about the target machine. This json output contains lots of variables and these are called Fact Variables.
Thus, based on the values of fact variables we can take decisions inside playbook while writing different tasks.
So, we can make use of ansible_os_family variable and depending on its value we can decide which module we can use to install the package on different types of target machines. Now, let’s write one more play for the database server (Centos7) as well. In this play, we are going to install MySQL service, start and enable this service. The package name for MySQL is maria-db.
Below is the updated playbook.
- -- - -hosts: WebServersGroup
- become: yes
- tasks: -name: Install httpd service
- yum: name: httpd
- state: present - name: Start and Enable httpd service
- service: name: httpd
- state: started
- enabled: yes - hosts: DBServerGroup
- become: yes
- tasks: -name: Install mariadb service
- yum: name: mariadb - server
- state: present - name: Start and Enable mariadb service
- service: name: mariadb
- state: started
- enabled: yes
Below command will execute our playbook.
- ansible-playbook web_db.yml
OUTPUT
We can see from the output that service has been installed successfully on database server.
We can also note that still, we are getting the error for web server 03, this we will fix in the next article where we are going to discuss the conditionals in playbooks.
So, for now, if we get syntax error while writing playbook we can simply check if there are any errors in the playbook even before executing the playbook with the below command:
- ansible-playbook web_db.yml --syntax-check
OUTPUT
Currently, there are no errors so it's not giving anything.
Summary
Finally, we can conclude and say that we have understood how local Ansible config can be written, we now know the playbook and we have also written our first playbook. I hope you are also now familiar with the fact variables. So, in the next article, we will take this forward and will learn a few more good things in Ansible.
You can also check out some of my previous articles of the series “Learning Ansible” here:
I hope you find this article helpful. Stay tuned for more … Cheers!!