↓ Naar de hoofdinhoud gaan

Ansible Componenten

·3022 woorden·15 mins
Inhoudsopgave

The ansible config file
#

Ansible.cfg
#

The ansible.cfg file is the configuration file for Ansible. It can be used to set various options and settings that control the behavior of Ansible and how it operates.

Some common options that can be set in the ansible.cfg file include:

  • inventory: This specifies the path to the inventory file that lists the hosts that Ansible will operate on.
  • library: This specifies the path to the directory containing Ansible modules.
  • module_utils: This specifies the path to the directory containing utility modules used by Ansible.
  • log_path: This specifies the path to the file where Ansible will log its output.
  • roles_path: This specifies the path to the directory containing Ansible roles.

There are many other options that can be set in the ansible.cfg file, and you can find more information about them in the Ansible documentation.

The ansible.cfg file contains settings for tweaking the ansible service on the control node.

  1. First, we will be generating a ansible.cfg default configuration file. The following command will generate a file with all settings disabled:
ansible-config init --disabled > ansible.cfg
  1. The following modification to the ansible file is for testing purposes only. We will set the host_key_checking variable to False to allow us to connect to target hosts without verifying the SSH key. In a production environment, it is strongly recommended to import the keys. When you are in the /etc/ansible directory, edit the ansible.cfg file.
sudo nano ansible.cfg
  1. Next, find the host_key_checking entry (you can search in nano by pressing CTRL + W and entering the search term) Remove the ‘;’ in front of the entry and enter the following:
host_key_checking=False

The inventory file
#

Ansible Inventory is a file that contains a list of hosts, which are the servers or devices that Ansible will manage. In its most basic form, the inventory file is just a flat list of hosts (or also called “Targets”). However, in more advanced , enterprise deployments, the inventory file is frequently hosted on a Git repository (Github or Gitlab for example). The added value of extra source control helps teams collaborate and track changes made to the inventory file.

The inventory file defines groups of hosts, which allow you to apply actions to multiple servers at once. In this chapter, we will start with some simple examples of how to define hosts with usernames and passwords in the inventory file, and then show how to use groups and variables.

When you installed ansible, a default inventory file can be found in the directory /etc/ansible/hosts.

Inventory breakdown
#

the following structure is used within a basic inventory file.

[<group name>]
<optional alias name> <IP address> <parameters>

[<group name>:vars]
<specific variable>=<value>
Using this structure, we could construct the following inventory:
[linux_hosts]
webserver1 ansible_host=192.168.5.2 ansible_user=davy ansible_password=SuperVeiligWachtwoordVanDavy

Special characters in passwords
#

When the password you are using to connect to a target hosts contains special characters (like ‘#’, ‘!’, ‘ç’,… ), Ansible will attempt to parse it as a special character. If you want to negate this (so it can be used like a normal character), you have to add a backslash ‘\’. An example: you have a target hosts with the following password:
ThisIsADifficult#password

The following would cause an error:

webserver1 ansible_host=10.10.10.10 ansible_user=davy ansible_password=ThisIsADifficult#password

To negate the special # character, it has to be defined as follows:

webserver1 ansible_host=10.10.10.10 ansible_user=davy ansible_password=ThisIsADifficult\#password
The backslash will not be used in the password when connecting to the host, it simply negates the special character when ansible parses the inventory file.

Parameter overview
#

The inventory file can be used to define variables for hosts, groups, and even all hosts in the inventory. These variables can be used to customize the behavior of Ansible playbooks, such as setting connection parameters, defining host-specific variables, and more.

Here are some of the commonly used parameters that can be used in an inventory file:

  • ansible_host: the IP address or hostname of the host. This is used by Ansible to connect to the host via SSH or other connection plugins.
  • ansible_user: the username to use when connecting to the host.
  • ansible_port: the SSH port number to use when connecting to the host. The default value is 22.
  • ansible_ssh_private_key_file: the path to the private key file to use for SSH authentication.
  • ansible_password: the password to use when connecting to the host. This is not recommended for security reasons and should be used only as a last resort.
  • ansible_ssh_pass: an alternative to ansible_password that specifies the password to use when connecting to the host via SSH. This is also not recommended for security reasons and should be used only as a last resort.
  • ansible_connection: the connection plugin to use when connecting to the host. The default value is ssh, but other plugins such as winrm, local or docker can be used for connecting to different types of hosts.
  • ansible_become: a boolean value that determines whether to use privilege escalation when running commands on the host. The default value is false.
  • ansible_become_user: the username to use for privilege escalation when running commands on the host.
  • ansible_become_password: the password to use for privilege escalation when running commands on the host. This is not recommended for security reasons and should be used only as a last resort.
  • ansible_shell_type: the shell type to use when running commands on the host. The default value is sh, but other shells such as bash or zsh can be used.

Variables in the inventory file
#

Say you have a group of 10 servers who have a simular naming convention and can be queried by using the same username and password. Say they are named as follows:

  • Webserver01
  • Webserver02
  • …
  • Webserver10

Instead of adding 10 lines into the inventory file, you could add them as one single line using the following pattern:

webserver[01-10].lab.local ansible_user=webadmin ansible_password=Webadminsecretpass

Basic Examples
#

Linux Server
#

Suppose we have a Linux server with IP address 192.168.1.10, and we want to manage it with Ansible using the username ansibleuser and password password123. We can define this host in our inventory file like this:

[linux_servers]
linux1 ansible_host=192.168.1.10 ansible_user=ansibleuser ansible_password=password123

In this example, we have created a group called

\[linux-servers\]

and added our Linux server to that group. We have also specified the ansible_user and ansible_password variables to tell Ansible how to connect to the server.

Windows Server
#

Similarly, suppose we have a Windows server with IP address 192.168.1.20, and we want to manage it with Ansible using the username ansibleuser and password password123. We can define this host in our inventory file like this:

[windows_servers]
win1 ansible_host=192.168.1.20 ansible_user=ansibleuser ansible_password=password123 ansible_connection=winrm ansible_winrm_transport=ntlm

In this example, we have created a group called

\[windows-servers\]

and added our Windows server to that group. We have also specified the ansible_user, ansible_password, ansible_connection, and ansible_winrm_transport variables to tell Ansible how to connect to the server using WinRM.

Cisco Switch
#

Suppose we have a Cisco switch with IP address 192.168.1.30, and we want to manage it with Ansible using the username ansibleuser and password password123. We can define this host in our inventory file like this:

[cisco_switches]
access_SWBlockD ansible_host=192.168.1.30 ansible_user=ansibleuser ansible_password=password123 ansible_connection=network_cli

In this example, we have created a group called

\[cisco-switches\]

and added our Cisco switch to that group. We have also specified the ansible_user, ansible_password, and ansible_connection variables to tell Ansible how to connect to the switch using the network_cli connection plugin.

Using Groups and Variables
#

Group Vars
#

In the previous examples, we specified the username and password for each host individually. If we have many hosts, it can be tedious to specify these variables for each one. Instead, we can use group variables to specify the variables for a group of hosts.

For example, suppose we have a group of Linux servers and we want to use the same username and password for all of them. We can define a group variable in our inventory file like this:

[linux_servers]
server1 ansible_host=192.168.1.10
server2 ansible_host=192.168.1.11

[linux_servers:vars]
ansible_user=ansibleuser
ansible_password=password123

In this example, we have defined a group of Linux servers, and then defined a group variable for that group using the

\[groupname:vars\]

syntax. The ansible_user and ansible_password variables will apply to all hosts in the linux-servers group.

Child groups
#

Child groups are defined using the \[child-group:children\] syntax in the inventory file, where child-group is the name of the child group, and children is the keyword that specifies the parent group. Any settings defined in the parent group will be inherited by the child group, including any host or variable definitions.

Child groups are useful for organizing your inventory file and simplifying the definition of properties and variables for related hosts. You can use them to group hosts by function, environment, or any other category that makes sense for your infrastructure.

Example 1: Child Groups in the Linux Server Group
#

Suppose we have a group of Linux servers that we want to divide into two child groups, web-servers and db-servers, and we want to define different variables for each child group.

We can define our inventory file like this:

[linux_servers]
server1 ansible_host=192.168.1.10
server2 ansible_host=192.168.1.11
server3 ansible_host=192.168.1.12

[web_servers:children]
linux_servers

[db_servers:children]
linux_servers

[web-servers:vars]
http_port=8080

[db-servers:vars]
db_port=3306

In this example, we have created a group called linux-servers with three hosts. We have then defined two child groups, web-servers and db-servers, that both inherit from linux-servers. We have also defined different variables for each child group.

When we run an Ansible playbook that targets web-servers, Ansible will run the playbook against all hosts in the web-servers group, which includes all hosts in the parent group linux-servers. Ansible will also use the http_port variable for all hosts in the web-servers group.

Similarly, when we run an Ansible playbook that targets db-servers, Ansible will run the playbook against all hosts in the db-servers group, which includes all hosts in the parent group linux-servers. Ansible will also use the db_port variable for all hosts in the db-servers group.

Example 2: Child Groups in the Windows Server Group
#

Suppose we have a group of Windows servers that we want to divide into two child groups, dev-servers and prod-servers, and we want to define different connection variables for each child group.

[windows_servers]
server1 ansible_host=192.168.1.20
server2 ansible_host=192.168.1.21
server3 ansible_host=192.168.1.22

[dev_servers:children]
windows_servers

[prod_servers:children]
windows_servers

[dev_servers:vars]
ansible_user=devuser
ansible_password=devpass

[prod_servers:vars]
ansible_user=produser
ansible_password=prodpass

In this example, we have created a group called windows-servers with three hosts. We have then defined two child groups, dev-servers and prod-servers, that both inherit from windows-servers. We have also defined different connection variables for each child group.

When we run an Ansible playbook that targets dev-servers, Ansible will run the playbook against all hosts in the dev-servers group, which includes all hosts in the parent group windows-servers. Ansible will also use the ansible_user and ansible_password variables for all hosts in the dev-servers group.

Similarly, when we run an Ansible playbook that targets prod-servers, Ansible will run the playbook against all hosts in the prod-servers group, which includes all hosts in the parent group windows-servers. Ansible will also use the ansible_user and ansible_password variables for all hosts in the prod-servers group.

Configuring Ansible to use keypair authentication
#

In the Ansible configuration file (ansible.cfg), specify the private key:

[defaults]
private_key_file = ~/.ssh/id_rsa

Or alternatively, set it in the inventory file (this is the preferred way as it’s way more granular)

Add the following entry at the host or group you wish to authenticate to using a keypair:

ansible_ssh_private_key_file=~/.ssh/id_rsa

Full example rule:
kasm ansible_host=172.16.90.10 ansible_user=davy.cavens ansible_ssh_private_key_file=~/.ssh/id_rsa 

Modules and plugins
#

As you can see in the example commands on the previous page, ansible uses ‘modules’. Ansible modules are small pieces of code that are responsible for carrying out specific tasks on remote hosts. Modules can be thought of as building blocks that are combined together to form playbooks or specify actions for ad-hoc commands, which are then used to automate tasks on one or more remote hosts. Modules can be written in any programming language and are responsible for defining the tasks that are carried out during an Ansible playbook run.

We’ll go through some of the most frequently used modules.

File
#

The file module is used to manage files and directories on remote hosts. This module can be used to create, modify, and delete files and directories, as well as change file permissions and ownership.
The following example creates a specific file on a remote host:

- name: Create file
  hosts: webservers
  tasks:
    - name: Create file with specific content
      file:
        path: /var/www/html/index.html
        state: touch
        owner: apache
        group: apache
        mode: '0644'
        content: "<html><head><title>Hello World</title></head><body><h1>Hello World</h1></body></html>"

Copy
#

The copy module is used to copy files from the Ansible control machine to one or more remote hosts. This module can also be used to set file permissions and ownership.

The following example copies a file to a remote host:

- name: Copy file
  hosts: webservers
  tasks:
    - name: Copy file to remote host
      copy:
        src: /path/to/local/file
        dest: /path/to/remote/file
        owner: apache
        group: apache
        mode: '0644'

Yum & APT
#

The yum and APT modules are used to manage packages on remote hosts. This includes installing, updating or removing packages. Yum is used for RHEL based distributions, APT is used for Debian based distributions.

An example using Yum:

- name: Install package
  hosts: webservers
  tasks:
    - name: Install package using YUM
      yum:
        name: httpd
        state: present

Service
#

The service module is used to manage services on remote hosts. This module can be used to start, stop, restart, and enable/disable services.
The following example starts a service on a remote host:

- name: Start service
  hosts: webservers
  tasks:
    - name: Start service on remote host
      service:
        name: httpd
        state: started

Shell
#

The shell module is used to execute arbitrary shell commands on remote hosts. This module can be used to run complex commands that cannot be handled by other Ansible modules.
The following example runs a shell command on a remote host:

- name: Run command
  hosts: webservers
  tasks:
    - name: Run command on remote host
      shell: ls -la /var/www/html

Template
#

The template module is used to generate files from templates on the Ansible control machine and copy them to one or more remote hosts. This module can be used to create configuration files that are customized for each remote host.
The following example generates a file from a template and copies it to the remote host:

- name: Generate file
  hosts: webservers
  tasks:
    - name: Generate file from template and copy to remote host
      template:
        src: /path/to/template.conf.j2
        dest: /etc/httpd/conf.d/custom.conf

Lineinfile
#

The lineinfile module can be used to add a line to a specific file on the target’s filesystem.
An example:

- name: Add a line to a file
  lineinfile:
      path: /etc/hosts
      line: 192.168.1.99 foo.lab.net foo

Other modules?
#

The ansible Galaxy contains more than 700 different modules. Not all modules are installed on an ansible controller by default.
You can install non-default modules using the ansible-galaxy command:

ansible-galaxy collection install cisco.ios

You can find an overview of all modules in the Ansible Galaxy

Collections
#

In Ansible, collections are a distribution format for Ansible content that can include playbooks, roles, modules, and plugins. Collections allow you to package and distribute Ansible content, whether it’s for sharing with others or for your own organizational use. They provide a structured way to deliver various components in a single package, simplifying the management, installation, and use of Ansible content.

Before collections, most Ansible content was either distributed as standalone roles via Ansible Galaxy or integrated directly into Ansible itself. Collections aim to offer more scalability and distribution flexibility than the older methods.

Features and Benefits of Collections
#

  1. Structured Layout: Collections have a defined directory structure, which allows content creators to organize and package their content in a predictable way.
  2. Versioning: You can version a collection, making it easier to manage and use different versions of content.
  3. Dependency Management: Collections can declare dependencies on other collections or content, ensuring that all required components are present.

Examples
#

  1. Vendor-Specific Collections: Many IT vendors have started packaging their modules and plugins into collections. For instance, Cisco, Juniper, or Red Hat might have their own collections for managing their specific products.
  2. Function-Specific Collections: Collections might focus on specific functions or tasks, like a collection for monitoring solutions, one for database management, and another for web server setups.
  3. Community Collections: The Ansible community might create collections for general purposes or specific needs, and these can be shared and distributed through platforms like Ansible Galaxy.

Using Collections
#

Here’s a basic example to illustrate how you might use a collection in a playbook:

---
- hosts: localhost
  gather_facts: no
  tasks:
    - name: Use a module from a collection
      namespace.collection_name.module_name:
        parameter1: value1

In this example, namespace is the namespace of the collection (often the name of the organization or individual who created it), collection_name is the name of the collection, and module_name is the name of the module within that collection.

Installing Collections
#

To install a collection from Ansible Galaxy:

ansible-galaxy collection install namespace.collection_name

For instance, if you wanted to install the community collection for managing Kubernetes:

ansible-galaxy collection install community.kubernetes

This is another example to install the community edition of the Cisco collection:

ansible-galaxy collection install cisco.ios

In summary, collections in Ansible provide a way to bundle, distribute, and version Ansible content in an organized and scalable manner. Whether you’re a content creator or an end user, collections offer a streamlined approach to managing and using Ansible’s expansive capabilities.

Where are they stored?
#

All collections that you have downloaded are stored locally on your controller. When you download a collection, they are stored in a hidden .ansible folder on your user’s home directory. Take a look at the following screenshot for more details:

ansible

You can also list all the collections and their saved directories by entering the following command:

ansible-galaxy collection list

This will show the following (example) output:

ansible

Updating a collection
#

To update a collection, you can simply enter the following command:

ansible-galaxy collection install -U <collection.name>

The following example updates the cisco.ios collection:

ansible-galaxy collection install -U cisco.ios

This will have the following output:

ansible
ansible

If the collection has any dependencies, they are updated as well.

Interesting links #