Manage variables, secrets and facts

Manage variables, secrets and facts

Introduction to ansible variable

Define the meaning of variables: replace some values in playbook with variables, so as to simplify the writing of playbook
The variable contains values: the user to create, the software package to install, the service to restart, the file to delete, and the document to retrieve from the Internet
Format of command variable: the variable name must start with a letter and can only contain letters, numbers and underscores
Example: web_server,remote_file,file1
Define three range levels for variables:
(1) global scope: variables set from the command line or ansible configuration
(2) play range: variables set in play and related structures
(3) host range: tasks collected or registered by lists, facts, and variables set on host groups and individual hosts

Variable command format

Starts with a letter and can only contain letters, numbers and underscores. Numbers cannot appear at the beginning.

Invalid variable nameValid variable name
web serverweb_server
remote.fileremote_file
1st filefile_1 file1
remoteserver$1remote_server_1 remote_server1

Variables defined in playbook

1. Common method: in vars at the beginning of playbook
---
- hosts: 192.168.240.40
  vars:		#Using vars module
    user: ttxx		#Define the variable user as ttxx
    home: /etc/ttxx 	#Define user's home directory i / etc/ttxx
2. Define the playbook variable in an external file

The playbook variable is defined in an external file. Instead of using the vars block in the playbook, you can use vars instead_ The files directive, followed by a list of external variable file names relative to the playbook position

---
- hosts: 192.168.240.40
  vars_files:
    - asnible/playbook/ttxxs.yml

Using variables in playbook

Once variables are declared, they can be used in tasks. To reference a variable, you can put the variable name in double braces. When the task is executed, Ansible replaces the variable with its value.

---
- hosts: 192.168.240.40
  vars:
    user: txt
  tasks: 
    - name: creates the user
      user: 
        name: "{{ user }}"

Variable classification: host variable and group variable

The list variables directly applied to the host are divided into two categories:
(1) host variable: applied to a specific host
(2) group variable: applied to a host group or all hosts in a group of hosts
Host variables take precedence over group variables, but variables defined in playbook are higher than both.

[http]		#Define host variables
192.168.240.40 ansible_user=root ansible_password=1

[servers]		#Define the servers host group user group variable
192.168.240.40
192.168.240.40

[servers:vars]
user=txt

[serversn]		#Defines the user group variable for the servers group, which consists of two hosts, with two servers in each host group
node1.example.com
node2.example.com

[serverss]
node3.example.com
node4.example.com

[servers:children]
serversn
serverss

[servers:vars]
user=txt

Populate host and group variables with directories

The preferred way to define variables for hosts and host groups is to create groups in the same working directory as the manifest file or directory_ Vars and host_vars two directories. These two directories contain files for defining group variables and host variables, respectively.

The recommended practice is to use host_vars and groups_ The vars directory defines manifest variables instead of defining them directly in the manifest file.

In order to define the group variable for the clients group, you need to create a group named group_ The YAML file of vars / clients, and then the contents of the file will set the variable to the value using the same syntax as playbook.

In order to define host variables for a specific host, you need to set the host_ Create a file with a name matching the host in the vars directory to store the host variables.

#Populate host real columns
[root@localhost ansible]# mkdir host_vars	#Create host_vars and groups_ Vars two files
[root@localhost ansible]# mkdir group_vars
[root@localhost ansible]# ls
ansible.cfg  cctv  group_vars  hosts  host_vars  httpd.conf  index.php  playbook  playbook.tar.gz  roles  text.yml  www.conf

[root@localhost ansible]# cat host_vars/192.168.240.40 at host_ Writing variable files in vars
ansible_user: root
ansible_password: 1

[root@localhost ansible]# cat cctv  	#The user password in the file no longer exists
[http]
192.168.240.40 

[root@localhost ansible]# ansible 192.168.240.40 -m  ping	#Test whether it can ping
192.168.240.40 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

If you need to define a common value for all servers in two data centers, you can set a group variable for the datacenter host group:

[root@localhost ansible]# cat group_vars/datacenter1
package: httpd
[root@localhost ansible]# cat group_vars/datacenter2
package: apache2

If you want to define different values for each host in each data center, define variables in a separate host variable file:

[root@localhost ansible]# cat host_vars/node1.example.com 
package: httpd
[root@localhost ansible]# cat host_vars/node2.example.com 
package: httpd2
[root@localhost ansible]# cat host_vars/node3.example.com 
package: apache2
[root@localhost ansible]# cat host_vars/node4.example.com 
package: mysq-server

If the directory structure of the above sample project contains all the above sample files, it will be as follows:

[root@localhost ansible]# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg
├── cctv
├── group_vars
│   ├── datacenter1
│   └── datacenter2
├── hosts
├── host_vars
│   ├── 192.168.240.40
│   ├── node1.example.com
│   ├── node2.example.com
│   ├── node3.example.com
│   └── node4.example.com
├── httpd.conf
├── index.php
├── playbook
│   ├── 192.168.240.40
│   ├── become.yml
│   ├── group_vars
│   ├── host_vars
│   ├── lamp.yml
│   └── ttxxs.yml

Override variables from the command line

In addition to allocating the configuration data related to the same element (package list, service list, user list, etc.) to multiple variables, arrays can also be used. One advantage of this approach is that arrays are browsable.

For example, suppose the following code snippet:

user1_first_name: use1
user1_last_name: user
user1_home_dir: /usr/txt
user2_first_name: bas
user2_last_name: base
user2_home_dir: /usr/base

This can be rewritten into an array named users:

users:
  bjones:
    first_name:use1
    last_name: user
    home_dir: /usr/txt
  acook:
    first_name: bas
    last_name: base
    home_dir: /usr/base

Example:

[root@localhost ansible]# cat host_vars/192.168.240.40 
ansible_user: root
ansible_password: 1

info:			#Write user address and domain name
  exie1:
    ip: 11.11.11.11
    domain: 123.com
  exit2:
    ip: 22.22.22.22
    domain: baidu.com

[root@localhost ansible]# cat text.yml 
---
- hosts: 192.168.240.40
  vars:
    ip:
  tasks: 
    - name: user
      lineinfile: 
        psth: /etc/hosts
        line: "{{ info.exie1.ip }} {{ info.exie1.domain  }}"	#Define variables
        state: present
[root@localhost ansible]# ansible-playbook text.yml   #Perform test

PLAY [192.168.240.40] *********************************************************************

TASK [Gathering Facts] ********************************************************************
ok: [192.168.240.40]

TASK [user] *******************************************************************************
changed: [192.168.240.40]

PLAY RECAP ********************************************************************************
192.168.240.40             : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
[root@localhost ~]# cat /etc/hosts		#see
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
11.11.11.11 123.com

Note: from this, the variable is more flexible. And there are many more complex and many more simple

Dot notation can cause problems if the key names are the same as those of python methods or properties, such as discard, copy, and add. Using bracket notation helps avoid conflicts and errors.

However, it should be noted that the two syntax described above are valid, but in order to facilitate troubleshooting, it is recommended to adopt one syntax consistently in all files of any given Ansible project.

Capture command output using registered variables

You can use the register statement to capture command output. The output is stored in a temporary variable and can then be used in the playbook for debugging purposes or for other purposes, such as specific configurations based on command output.

The following playbook demonstrates how to capture command output for debugging purposes:

[root@localhost ansible]# cat lq.yml 
---
- name: lql
  hosts: 192.168.240.40
  tasks:
    - name: llqq
      yum:
        name: php
        state: present
      register: install_result

    - debug: var=install_result

When running the playbook, the debug module is used to install_result dump the value of the registered variable to the terminal.

[root@localhost ansible]# ansible-playbook lq.yml 

PLAY [lql] ********************************************************************************

TASK [Gathering Facts] ********************************************************************
ok: [192.168.240.40]

TASK [llqq] *******************************************************************************
changed: [192.168.240.40]

TASK [debug] ******************************************************************************
ok: [192.168.240.40] => {
    "install_result": {
        "changed": true,
        "failed": false,
        "msg": "",
        "rc": 0,
        "results": [
            "Installed: php-fpm-7.2.24-1.module_el8.2.0+313+b04d0a66.x86_64",
            "Installed: php-cli-7.2.24-1.module_el8.2.0+313+b04d0a66.x86_64",
            "Installed: php-common-7.2.24-1.module_el8.2.0+313+b04d0a66.x86_64",
            "Installed: php-7.2.24-1.module_el8.2.0+313+b04d0a66.x86_64",
            "Installed: nginx-filesystem-1:1.14.1-9.module_el8.0.0+184+e34fea82.noarch"
        ]
    }
}

PLAY RECAP ********************************************************************************
192.168.240.40             : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Management Secrets

Ansible Vault

Ansible may need to access sensitive data such as passwords or API keys in order to be able to configure the managed host. Typically, this information may be stored in plain text in manifest variables or other ansible files. However, if so, any user who has access to ansible files or the version control system storing these ansible files can access this sensitive data. This indicates a security risk.

Ansible Vault provided by ansible can encrypt and decrypt any structured data file used by ansible. To use Ansible Vault, you can create, edit, encrypt, decrypt, and view files through a command-line tool called Ansible Vault. Ansible Vault can encrypt any structured data file used by ansible. This may include manifest variables, variable files contained in the playbook, variable files passed as parameters when the playbook is executed, or variables defined in the ansible role.

Create encrypted file

To create a new encrypted file, use the ansible vault create filename command. The command prompts for a new vault password and opens the file using the default EDITOR vi. We can set and export EDITOR environment variables and specify other default editors by setting and exporting. For example, to set the default EDITOR to nano, set export EDITOR=nano.

[root@localhost ansible]# ansible-vault create ppp.yml		#New encrypted file
New Vault password: 
Confirm New Vault password: 

[root@localhost ansible]# cat ppp.yml 	#View encrypted
$ANSIBLE_VAULT;1.1;AES256
33646166636362376437303263656132613865663230653838616265653561336666656532653663
3035383664343533646639666333353931626462386331650a376333653464373538353237363730
39376236623063373139663363663034323038343962613266373733646132353461613036646366
6338326434393862620a303830666163316331323363376362336635373664653961353135613336
3839

We can also use the vault password file to store the vault password instead of entering the vault password through the standard input path. Doing so requires using file permissions and other means to closely protect the file.

ansible-vault create --vault-password-file=vault-pass secret.yml
View encrypted files

You can use the Ansible Vault view filename command to view an Ansible Vault encrypted file without having to open it for editing.

[root@localhost ansible]# ansible-vault view ppp.yml
Vault password: 
gegegegerfege

Edit an existing encrypted file

To edit an existing encrypted file, Ansible Vault provides the Ansible Vault edit filename command. This command decrypts the file as a temporary file and allows editing. When you save, it copies its contents and deletes temporary files.

[root@localhost ansible]# ansible-vault view ppp.yml	#Original document content
Vault password: 
gegegegerfege		
[root@localhost ansible]# ansible-vault edit ppp.yml	#Enter modify
Vault password: 
[root@localhost ansible]# ansible-vault view ppp.yml    #see
Vault password: 
gegegegerfeg
fefwe
fewfee

The edit subcommand always overwrites the file, so you should only use it when making changes. To view the contents of a file without making changes, use the view subcommand.

Encrypt existing files

To encrypt an existing file, use the ansible vault encrypt filename command. This command takes the names of multiple files to be encrypted as parameters.

[root@localhost ansible]# ansible-vault encrypt lq.yml  #Encryption can encrypt multiple files at the same time
New Vault password: 
Confirm New Vault password: 
Encryption successful

Use * * – output=OUTPUT_FILE option to save the encrypted file with a new name. Only one input file can be used with the – output * * option.

Decrypt existing files

Existing encrypted files can be permanently decrypted through the ansible vault decrypt filename command. When decrypting a single file, you can use the * * – output * * option to save the decrypted file with a different name.

[root@localhost ansible]# ansible-vault decrypt lq.yml 
Vault password: 
Decryption successful

Change password for encrypted file

Use the ansible vault rekey filename command to change the password for the encrypted file. This command can update the keys of multiple data files at one time. It will prompt for the original password and the new password.

[root@localhost ansible]# ansible-vault rekey ppp.yml 
Vault password: 
New Vault password: 
Confirm New Vault password: 
Rekey successful

When using vault password file, you can use – new vault password file

ansible-vault rekey --new-vault-password-file=NEW_VAULT_PASSWORD_FILE secret.yml

Keywords: Linux

Added by Grant Cooper on Sat, 15 Jan 2022 04:52:20 +0200