参考1 参考2
Ansible templates 由 Jinja2 templating language 来编写.
使用 template 主要是为了能在文档中展开 dynamic variables, 语法如 {{ variable_here }}
.
简述 Jinja2 template 一般以 .j2
作为 Jinja2 template 的后缀 (主要是方便编辑器识别)
Ansible facts 参考
Ansible facts 是一些从 target nodes 上收集到的 data (IP, BIOS 信息, software, hardware info 等), 其用 JSON 格式保存, 可以通过 ansible_facts
变量访问.
不同系统的 fact 信息不同, 如:
1 2 3 4 5 6 7 8 9 10 - hosts: all tasks: - package: name: "httpd" state: present when ansible_facts["os_name"] == "RedHat" - package: name: "apache2" state: present when ansible_facts["os_name"] == "Ubuntu"
访问 facts 在运行 playbook 前, Ansible 会用 setup
module 来收集 facts 信息.
用 ad-hoc 命令获取 获取所有主机的全部 facts 信息:
1 ansible all -m setup -i inventory.yaml
输出如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 fedora1 | SUCCESS => { "ansible_facts" : { "ansible_all_ipv4_addresses" : [ "192.168.177.24" ] , "ansible_all_ipv6_addresses" : [ "fe80::5054:ff:fe87:4814" ] , "ansible_apparmor" : { "status" : "disabled" } , "ansible_architecture" : "x86_64" , "ansible_bios_date" : "04/01/2014" , "ansible_bios_vendor" : "SeaBIOS" , "ansible_bios_version" : "Arch Linux 1.16.3-1-1" , "ansible_board_asset_tag" : "NA" , "ansible_board_name" : "NA" , "ansible_board_serial" : "NA" , "ansible_board_vendor" : "NA" , "ansible_board_version" : "NA" , "ansible_chassis_asset_tag" : "NA" , "ansible_chassis_serial" : "NA" , "ansible_chassis_vendor" : "QEMU" , "ansible_chassis_version" : "pc-q35-8.2" , ... ...
可以通过设置 filter
来获取特定信息:
1 ansible all -m setup -a "filter=ansible_cmdline" -i inventory.yaml
输出如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 fedora2 | SUCCESS => { "ansible_facts" : { "ansible_cmdline" : { "BOOT_IMAGE" : "(hd0,gpt2)/boot/vmlinuz-6.2.9-300.fc38.x86_64" , "quiet" : true , "rhgb" : true , "ro" : true , "root" : "UUID=a08a148f-27f0-42e4-89d2-c93870c44df3" } , "discovered_interpreter_python" : "/usr/bin/python3" } , "changed" : false } fedora1 | SUCCESS => { "ansible_facts" : { "ansible_cmdline" : { "BOOT_IMAGE" : "(hd0,gpt2)/boot/vmlinuz-6.2.9-300.fc38.x86_64" , "quiet" : true , "rhgb" : true , "ro" : true , "root" : "UUID=a82caaa6-edd3-4d6e-b330-5a77456c6e9f" } , "discovered_interpreter_python" : "/usr/bin/python3" } , "changed" : false }
在 playbook 中使用 在 playbook 中访问 facts 条目时, 需要使用原条目去掉 ansible
之后的名称, 如 ansible_facts["system"]
而不是 ansible_facts["ansible_system"]
.
如:
1 2 3 4 - hosts: all tasks: - debug: var: ansible_facts
输出如:
输出指定条目:
1 2 3 4 - hosts: all tasks: - debug: var: ansible_facts["cmdline"]
输出如:
示例 配置 httpd 的示例 编写 httpd.conf.j2 Apache 配置 template httpd.conf.j2
文件的内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 # This is the main Apache HTTP server configuration file # # {{ ansible_managed }} ServerRoot "/etc/httpd" Listen {{ http_port }} Include conf.modules.d/*.conf User apache Group apache ServerAdmin {{ admin }}@{{ ansible_hostname }} <Directory /> AllowOverride none Require all denied </Directory> DocumentRoot "{{ content_dir }}" <Directory "{{ content_dir }}"> AllowOverride none # Allow open access: Require all granted </Directory> <Directory "{{ content_dir }}"> Options Indexes FollowSymLinks AllowOverride none Require all granted </Directory> <IfModule dir_module> DirectoryIndex index.html </IfModule> <Files ".ht"> Require all denied </Files> ErrorLog "logs/error_log" LogLevel warn <IfModule log_config_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common <IfModule logio_module> LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio </IfModule> CustomLog "logs/access_log" combined </IfModule> <IfModule /> ScriptAlias /cgi-bin/"/var/www/cgi-bin" </IfModule> <Directory "/var/www/cgi-bin"> AllowOverride none Options none Require all granted </Directory> <IfModule mime_module> TypesConfig /etc/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz AddType text/html .shtml AddOutputFilter INCLUDES .shtml </IfModule> AddDefaultCharset UTF-8 <IfModule mime_magic_module> MIMEMagicFile conf/magic </IfModule> EnableSendFile on IncludeOptional conf.d/*.conf
编写 index.html.j2 template index.html.j2
文件的内容为:
1 2 3 4 5 Welcome to {{ ansible_hostname }} -The ipv4 address is {{ ansible_default_ipv4['address']}} -The current memory usage is {{ ansible_memory_mb['real']['used']}}mb out of {{ ansible_memory_mb['real']['total']}}mb -The {{ ansible_devices | first }} block device has the following partitions: -{{ ansible_devices['vdb']['partitions'] | join('\n -')}}
Apache template playbook apache-template.yml
文件内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 - hosts: ansible01.test.lab become: true vars: http_port: 8080 admin: ansible-devops content_dir: /webcontent tasks: - name: Create Group for Webcontent group: name: webcontent state: present - name: Create Webcontent Dir file: path: /webcontent state: directory group: webcontent owner: ansible-devops mode: '2775' - name: set mode to enforcing selinux: policy: targeted state: enforcing - name: enable httpd cgi boolean seboolean: name: httpd_enable_cgi state: true persistent: true - name: Set SELinux Context on Directory sefcontext: target: "/webcontent(/.*)?" setype: httpd_sys_content_t state: present - name: run restorecon command: restorecon -irv /webcontent - name: push config template template: src: /home/vcirrus-consulting/RHCE-Ansible/templates/httpd.conf.j2 dest: /etc/httpd/conf/httpd.conf backup: true notify: "restart apache" - name: push index.html template template: src: /home/vcirrus-consulting/RHCE-Ansible/templates/index.html.j2 dest: /webcontent/index.html handlers: - name: restart web servers service: name: httpd state: restarted listen: "restart apache"
(注意在 playbook 中定义的 vars
可以在 template 中使用)
向 HTML Template 传入 list index.j2
文件的内容为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <!DOCTYPE html > <html > <body > <h1 > Best Breakfast Items</h1 > <ul > {% for breakfast_item in breakfast %} <li > {{ breakfast_item }} </li > {% endfor %}</ul > {% set today = ansible_date_time['weekday_number'] | int %} {% if today == 2 %} <p > Today is Tuesday, get a free coffe with your sandwich! </p > {% else %} <p > Stop in today for the best breakfast in town! </p > {% endif %}</body > </html >
playbook.yml
文件的内容为:
1 2 3 4 5 6 7 8 9 10 - name: Breakfast test hosts: servers vars: breakfast: ["Pepper and egg" , "Coffee" , "Giardiniera" ] tasks: - name: Call template template: src: ~/ansibledemo/demo.j2 dest: /var/www/html/demo.html