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 name | Valid variable name |
---|---|
web server | web_server |
remote.file | remote_file |
1st file | file_1 file1 |
remoteserver$1 | remote_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