Ansible
Ansible
Install
Sample 2.10.7 version:
sudo pip3 uninstall ansible ansible-base ansible-core sudo pip3 install ansible==2.10.7
Useful Variables
Useful magic variables
Discovering variables: facts and magic variables https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_vars_facts.html
To see the raw information gathered:
ansible <hostname> -m ansible.builtin.setup
Remember these:
{{ ansible_architecture }} == "x86_64" {{ ansible_default_ipv4.address }} == "x.x.x.x" {{ ansible_default_ipv4.interface }} == "eth0"
"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.5.1804", "ansible_kernel": "3.10.0-862.14.4.el7.x86_64", "ansible_machine": "x86_64",
"ansible_env": { "HOME": "/home/zuul", "PATH": "/usr/local/bin:/usr/bin", "USER": "zuul",
"ansible_fqdn": "centos-7-rax-dfw-0003427354", "ansible_hostname": "centos-7-rax-dfw-0003427354", "ansible_domain": "",
"ansible_lsb": { "codename": "Core", "description": "CentOS Linux release 7.5.1804 (Core)", "id": "CentOS", "major_release": "7", "release": "7.5.1804"
"ansible_memfree_mb": 7709,
"ansible_nodename": "centos-7-rax-dfw-0003427354", "ansible_os_family": "RedHat"
OS Version
{{ansible_distribution}} - Debian / Ubuntu {{ansible_distribution_release}} - buster / focal {{ansible_distribution_version}} - 10 / 18.04 {{ansible_distribution_major_version}} - 10 / 18
copy
copy - Copies files to remote locations — Ansible Documentation https://docs.ansible.com/ansible/2.6/modules/copy_module.html
- name: example copying file with owner and permissions copy: src: /srv/myfiles/foo.conf dest: /etc/foo.conf owner: foo group: foo mode: 0644
- name: example copying file with owner and permissions copy: src=foo.conf dest=/etc/foo.conf
Ansible Misc
~/metricbeat/metricbeat.yml
metricbeat.modules: - module: system metricsets: - cpu - filesystem - memory - network - process enabled: true period: 10s processes: ['.*'] cpu_ticks: false - module: docker metricsets: ["container", "cpu", "diskio", "healthcheck", "info", "memory", "network"] hosts: ["unix:///var/run/docker.sock"] period: 100s output.elasticsearch: hosts: ["test.oeey.com:9200"] setup.kibana: host: "test.oeey.com:8081"
---
Working With Playbooks — Ansible Documentation - https://docs.ansible.com/ansible/latest/user_guide/playbooks.html
Intro to Playbooks — Ansible Documentation - https://docs.ansible.com/ansible/2.5/user_guide/playbooks_intro.html
YAML Syntax — Ansible Documentation - https://docs.ansible.com/ansible/2.5/reference_appendices/YAMLSyntax.html#yaml-syntax
---
Here’s a playbook that contains just one play:
--- - hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: - name: ensure apache is at the latest version yum: name: httpd state: latest - name: write the apache config file template: src: /srv/httpd.j2 dest: /etc/httpd.conf notify: - restart apache - name: ensure apache is running (and enable it at boot) service: name: httpd state: started enabled: yes handlers: - name: restart apache service: name: httpd state: restarted
YAML
See YAML
YAML Syntax — Ansible Documentation - https://docs.ansible.com/ansible/2.5/reference_appendices/YAMLSyntax.html#yaml-syntax
Raspberry Pi
How to Setup the Raspberry Pi 3 Using Ansible | Datahovel - https://datahovel.com/2016/03/20/how-to-setup-the-raspberry-pi-using-ansible/
ansible-playground/raspbian-bootstrap at master · Condla/ansible-playground · GitHub - https://github.com/Condla/ansible-playground/tree/master/raspbian-bootstrap
Automating Raspberry Pi setup with Ansible - http://www.hietala.org/automating-raspberry-pi-setup-with-ansible.html
--
Raspbian Bootstrap
This is simple ansible playbook to setup one or more of your Raspberry Pis running a fresh Raspbian installation on it. I used the imag e from March 2016 available to download from the official website. This playbook bootstraps your Raspberry Pi 3 to be used over your WPA
Wifi network, if you provide a correct SSID and password as a playbook variable. It will additionally install software required to use
Amazon's AWS IoT NodeJS SDK. (http://docs.aws.amazon.com/iot/latest/developerguide/iot-device-sdk-node.html).
After the first time boot of your Raspberry Pi, follow these few steps in order to bootstrap your machine.
- Install Ansible and Git on your "Controller" machine.
- Clone this git repository.
- Configure hostname/IP address in the "hosts" file
- Unfortunately: Login to Raspi and expand SD card with "sudo raspi-config" -
This will be automated in the future!
- Exectute playbook
# Install Ansible and Git on the machine. sudo apt-get install python-pip git python-dev sshpass sudo pip install ansible # Clone this repo: git clone https://github.com/Condla/ansible-playground.git cd ansible-playground/raspbian-bootstrap/ # Configure IP address in "hosts" file. If you have more than one # Raspberry Pi, add more lines and enter details # Execute playbook ./playbook.yml
Small sample:
files: ansible.cfg files/ hosts playbook.yml README.md templates/
ansible.cfg:
[defaults] hostfile = ./hosts inventory = ./hosts
hosts:
[local] localhost
playbook.yml:
#!/usr/bin/env ansible-playbook --- - hosts: local gather_facts: yes connection: local vars: packages_to_install: [ build-essential, tree, ] pip_packages_to_install: [ pip, pySerial ] tasks: - name: install ubuntu packages apt: pkg={{ item }} state=present with_items: '{{packages_to_install}}' become: yes - name: install python modules pip: name={{ item }} with_items: '{{pip_packages_to_install}}' become: yes
---
helloworld-playbook.yml
#!/usr/bin/env ansible-playbook --- - name: This is a hello-world example hosts: local tasks: - name: Create a file called '/tmp/testfile.txt' with the content 'hello world'. copy: content="hello world\n" dest=/tmp/testfile.txt
Ansible – A “hello world” Playbook – Codingbee - https://codingbee.net/tutorials/ansible/ansible-a-hello-world-playbook
To avoid the "no host matching" use:
hosts: localhost
Hello World
Ansible – A “hello world” Playbook – Codingbee - https://codingbee.net/tutorials/ansible/ansible-a-hello-world-playbook
tower-example/helloworld.yml at master · ansible/tower-example · GitHub - https://github.com/ansible/tower-example/blob/master/helloworld.yml
--- - name: Hello World! # hosts: all hosts: localhost tasks: - name: Hello World! shell: echo "Hi! Ansible is working."
Inventory
ini version:
# inventory/hosts: [webservers] web1.example.com [fileservers] file1.example.com [all:children] webservers filservers
---
yaml version:
--- # inventory/hosts.yaml webservers: children: web11.example.com fileservers: children: file1.example.com all: children: webservers: children: more_webservers children: even_more_webservers fileservers:
Embedded Inventory
Crazy embedded inventory option:
- name: 'Parse dictionary hosts' hosts: 'localhost' vars: my_parsed_hosts: controller-a: name: 'controller-node' ansible_user: 'ubuntu' ansible_host: '10.0.10.1' my_variable: false worker-b: name: 'worker-node' ansible_user: 'ubuntu' ansible_host: '127.0.0.1' my_variable: false aws-worker-custom-c: name: 'aws-worker-custom' ansible_user: 'ubuntu' ansible_host: '192.168.42.128' my_variable: true tasks: - name: 'Add new hosts to this playbook from dictionary' ansible.builtin.add_host: name: '{{ item.value.name }}' ansible_user: '{{ item.value.ansible_user }}' ansible_host: '{{ item.value.ansible_host }}' my_variable: '{{ item.value.my_variable }}' groups: - 'worker_nodes' - 'grafana' with_dict: '{{ my_parsed_hosts }}' when: - ('worker_nodes' not in groups) - ('worker' in item.value.name) - (item.value.name not in ansible_play_hosts_all) - name: 'Use parsed dictionary hosts' hosts: 'worker_nodes' tasks: - name: 'Print debug welcome message' ansible.builtin.debug: msg: > Node {{ ansible_host }} says welcome!
Inventory Host Vars
sample inventory.ini:
[lab] unit1 description="system number 1" [lab:vars] somevar="another var" anothervar="another var"
to use in playbook:
{{ description }} and {{ somevar }}, etc
See:
- https://docs.ansible.com/ansible/2.7/user_guide/intro_inventory.html
- https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html
- https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html
Run Task when node in group
Run when in specific group: [1]
when: inventory_hostname in groups["appservers"]
when: ( inventory_hostname in groups["appservers"] or inventory_hostname in groups["webservers"] )
Logging
ansible.cfg:
[defaults] log_path = /var/log/ansible.log
Via ENV:
export ANSIBLE_LOG_PATH=~/ansible.log
Enable debug:
export ANSIBLE_DEBUG=True
Set Ansible Username and Password
NOTE: Before Ansible 2.0 "ansible_user" was "ansible_ssh_user". "ansible_password" or "ansible_pass" or "ansible_ssh_pass" or do all work?? " Option 1 - Inventory:
[master] 192.168.1.10 ansible_connection=ssh ansible_ssh_user=vagrant ansible_ssh_pass=vagrant
Option 2 - Inventory Vars:
[all:vars] ansible_connection=ssh ansible_port=22 ansible_user=vagrant ansible_pass=vagrant ?? # or ansible_ssh_pass=vagrant # or ansible_password=vagrant ?
Option 3 - group_vars/all:
--- # file: group_vars/all ansible_connection: ssh ansible_ssh_user: vagrant ansible_ssh_pass: vagrant
Option 4 - extra-vars
ansible --module-name ping \ --extra-vars 'ansible_user=domain\user ansible_password=PASSWORD' \ --inventory 10.10.6.184, all
ref:
- https://serverfault.com/questions/628989/how-to-set-default-ansible-username-password-for-ssh-connection
- https://stackoverflow.com/questions/37004686/how-to-pass-a-user-password-in-ansible-command
Apt
apt - Manages apt-packages — Ansible Documentatio - https://docs.ansible.com/ansible/latest/modules/apt_module.html
- name: Remove "foo" package apt: name: foo state: absent
- name: Install a list of packages apt: name: "{{ packages }}" vars: packages: - foo - foo-tools
name inline list: [2]
- name: Install MongoDB apt: pkg: - mongodb-org-server - mongodb-org-mongos - mongodb-org-shell - mongodb-org-tools state: latest update_cache: true
vars: mongo_packages: - mongodb-org-server - mongodb-org-mongos - mongodb-org-shell - mongodb-org-tools - name: Install mongodb yum: name: "{{ item }}-{{ mongo_version }}" state: present with_items: "{{ mongo_packages }}" notify: Restart MongoDB
- name: Install mongodb yum: name: "{{ item }}" state: present with_items: "{{ mongo_packages }}" notify: Restart MongoDB vars: mongo_packages: - mongodb-org-server - mongodb-org-mongos - mongodb-org-shell - mongodb-org-tools
Pip
Ansible Pip Module - Managing Python Packages - Ansible Tutorials - http://www.mydailytutorials.com/ansible-pip-module/
pip - Manages Python library dependencies — Ansible Documentation - https://docs.ansible.com/ansible/2.6/modules/pip_module.html
tasks: - name: Installing NumPy python library using Ansible pip module pip: name: NumPy
tasks: - name: Update Pip pip: name: pip state: latest - name: Specific fabric pip: name: fabric<2.0 - name: More Pip packages pip: name: python-jenkins jira slackclient
-
pip - Ansible: install multiple Python packages on a single session - Stack Overflow https://stackoverflow.com/questions/31396130/ansible-install-multiple-python-packages-on-a-single-session
- name: "Install Python Packages: {{ python_packages_to_install }}" pip: name={{ item }} with_items: "{{ python_packages_to_install }}" vars: python_packages_to_install: - fabric<2.0 - python-jenkins - jira - slackclient - xmodem - pySerial - numpy
NFS
mount - Control active and configured mount points — Ansible Documentation - https://docs.ansible.com/ansible/2.5/modules/mount_module.html
tasks: - name: nfs-store5 NFS mount: name: /nfs-store5 src: nfs-store5:/wbt fstype: nfs state: mounted
Dry Run
Dry Run: [1]
ansible-playbook --check playbook.yml
Include Playbook
- include: other.yml
And Include at different levels
Tasks: - include tasks.yml
Create Empty File
- name: ensure file exists copy: content: "" dest: /etc/nologin force: no group: sys owner: root mode: 0555
This will touch a file each time (yellow update each time) [2]
- name: create fake 'nologin' shell file: path=/etc/nologin state=touch owner=root group=sys mode=0555
With command module:
- name: Create file command: touch /path/to/file args: creates: /path/to/file
Remove File
- name: Clear Pi Warnings hosts: localhost tasks: - name: Remove pi password warning file: state: absent path: /etc/profile.d/sshpwd.sh - name: Remove Wifi warning file: state: absent path: /etc/profile.d/wifi-country.sh
Don't Fail on Error
- name: Do not count this as a failure ansible.builtin.command: /bin/false ignore_errors: true
ref: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_error_handling.html
Windows PATH
- name: Ensure that system32 and Powershell are present on the global system path, and in the specified order ansible.windows.win_path: elements: - '%SystemRoot%\system32' - '%SystemRoot%\system32\WindowsPowerShell\v1.0'
- name: Ensure that C:\Program Files\MyJavaThing is not on the current user's CLASSPATH ansible.windows.win_path: name: CLASSPATH elements: C:\Program Files\MyJavaThing scope: user state: absent
ref: https://docs.ansible.com/ansible/latest/collections/ansible/windows/win_path_module.html
Execute Script
script - Runs a local script on a remote node after transferring it — Ansible Documentation - https://docs.ansible.com/ansible/2.6/modules/script_module.html
# Example from Ansible Playbooks - script: /some/local/script.sh --some-arguments 1234 # Run a script that creates a file, but only if the file is not yet created - script: /some/local/create_file.sh --some-arguments 1234 args: creates: /the/created/file.txt # Run a script that removes a file, but only if the file is not yet removed - script: /some/local/remove_file.sh --some-arguments 1234 args: removes: /the/removed/file.txt # Run a script using a executable in a non-system path - script: /some/local/script args: executable: /some/remote/executable # Run a script using a executable in a system path - script: /some/local/script.py args: executable: python3
Execute Shell
shell - Execute commands in nodes. — Ansible Documentation - https://docs.ansible.com/ansible/2.5/modules/shell_module.html
- name: Execute the command in remote shell; stdout goes to the specified file on the remote. shell: somescript.sh >> somelog.txt - name: Change the working directory to somedir/ before executing the command. shell: somescript.sh >> somelog.txt args: chdir: somedir/ # You can also use the 'args' form to provide the options. - name: This command will change the working directory to somedir/ and will only run when somedir/somelog.txt doesn't exist. shell: somescript.sh >> somelog.txt args: chdir: somedir/ creates: somelog.txt - name: Run a command that uses non-posix shell-isms (in this example /bin/sh doesn't handle redirection and wildcards together but bash does) shell: cat < /tmp/*txt args: executable: /bin/bash - name: Run a command using a templated variable (always use quote filter to avoid injection) shell: cat {{ myfile|quote }} # You can use shell to run other executables to perform actions inline - name: Run expect to wait for a successful PXE boot via out-of-band CIMC shell: | set timeout 300 spawn ssh admin@{{ cimc_host }} expect "password:" send "{{ cimc_password }}\n" expect "\n{{ cimc_name }}" send "connect host\n" expect "pxeboot.n12" send "\n" exit 0 args: executable: /usr/bin/expect delegate_to: localhost
Download File
get_url - Downloads files from HTTP, HTTPS, or FTP to node — Ansible Documentation - https://docs.ansible.com/ansible/2.5/modules/get_url_module.html
- name: Download foo.conf get_url: url: http://example.com/path/file.conf dest: /etc/foo.conf mode: 0440 - name: Download file and force basic auth get_url: url: http://example.com/path/file.conf dest: /etc/foo.conf force_basic_auth: yes - name: Download file with custom HTTP headers get_url: url: http://example.com/path/file.conf dest: /etc/foo.conf headers: 'key:value,key:value' - name: Download file with check (sha256) get_url: url: http://example.com/path/file.conf dest: /etc/foo.conf checksum: sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c - name: Download file with check (md5) get_url: url: http://example.com/path/file.conf dest: /etc/foo.conf checksum: md5:66dffb5228a211e61d6d7ef4a86f5758 - name: Download file from a file path get_url: url: file:///tmp/afile.txt dest: /tmp/afilecopy.txt
Build Program from Source
Using Ansible to Compile NGINX from Sources with Custom Modules - https://medium.com/bigpanda-engineering/using-ansible-to-compile-nginx-from-sources-with-custom-modules-f6e6c6a42493
compile_nginx_from_sources.yml:
--- - name: Compile NGINX from sources hosts: webserver vars: nginx_version: nginx-1.13.4 nginx_tarball_url: "http://nginx.org/download/{{ nginx_version }}.tar.gz" nginx_install_dir: "/tmp/{{ nginx_version }}" nginx_sbin_path: "/usr/sbin/nginx" nginx_conf_path: "/etc/nginx/nginx.conf" nginx_custom_modules: "--with-http_auth_request_module" tasks: - name: Installing NGINX Dependencies become: yes apt: name: "{{ item }}" update_cache: yes with_items: - libssl-dev - zlib1g-dev - libpcre3 - libpcre3-dev - unzip - name: Downloading NGINX sources get_url: url: "{{ nginx_tarball_url }}" dest: "/tmp/{{ nginx_version }}.tar.gz" register: nginx_source - name: Unpacking NGINX unarchive: copy: no dest: /tmp/ src: "{{ nginx_source.dest }}" when: nginx_source.changed register: nginx_source_unpack - name: Create required Nginx dirs become: yes file: path: /etc/nginx state: directory owner: root mode: 0755 - name: Configuring NGINX source with custom modules command: "./configure --sbin-path={{ nginx_sbin_path }} --conf-path={{ nginx_conf_path }} {{ nginx_custom_modules }}" args: chdir: "{{ nginx_install_dir }}" when: nginx_source_unpack|changed register: nginx_configure - name: Installing NGINX become: yes shell: make && make install args: chdir: "{{ nginx_install_dir }}" when: nginx_configure|changed - name: Creating NGINX conf file become: yes template: src: nginx.conf dest: "{{ nginx_conf_path }}" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: 0644 - name: Installing NGINX init script (service) become: yes template: src: nginx.init dest: /etc/init.d/nginx owner: root group: root mode: 0755 - name: Starting NGINX become: yes service: name: nginx state: started
Build tio
tio.yml:
- name: Compile tio from sources hosts: localhost vars: tio_version: v1.30 tio_install_dir: "/root/.src/tio" tio_sbin_path: "/usr/local/bin/tio" tasks: - name: Git fun git: name: 'https://github.com/tio/tio.git' dest: "{{tio_install_dir}}" version: "{{tio_version}}" register: tio_git - name: Make tio configure command: "sh autogen.sh" args: chdir: "{{ tio_install_dir }}" creates: "{{tio_sbin_path}}" register: tio_make_configure - name: Configuring tio source command: "./configure" args: chdir: "{{ tio_install_dir }}" when: tio_make_configure|changed register: tio_configure - name: Installing tio become: yes shell: make && make install args: chdir: "{{ tio_install_dir }}" when: tio_configure|changed
Encrypt Files
vault-id:
# single password --vault-id pass # multiple passwords: --vault-id dev@passwords dev: mypassword
Note: vault id can also specify a script! [3]
ansible-playbook --vault-id dev@contrib/vault/vault-keyring-client.py
Create new file:
ansible-vault create --vault-id test@multi_password_file foo.yml
Encrypt existing:
ansible-vault encrypt foo.yml bar.yml baz.yml ansible-vault encrypt --vault-id project@prompt foo.yml bar.yml baz.yml
View encrypted file:
ansible-vault view foo.yml bar.yml baz.yml
Decrypt file:
ansible-vault decrypt foo.yml bar.yml baz.yml
Always use a password file:
alias ansible='ansible-playbook --vault-id /etc/ansible/password' alias ansible-playbook='ansible-playbook --vault-id /etc/ansible/password'
ref: [3]
Encrypt Variable
encrypt_string Encrypt a string
Usage:
ansible-vault encrypt_string <password_source> '<string_to_encrypt>' --name '<string_name_of_variable>'
Example: (encrypt 'foobar' using only password in a_password_file)
ansible-vault encrypt_string --vault-password-file a_password_file 'foobar' --name 'the_secret'
the_secret: !vault | $ANSIBLE_VAULT;1.1;AES256 62313365396662343061393464336163383764373764613633653634306231386433626436623361 6134333665353966363534333632666535333761666131620a663537646436643839616531643561 63396265333966386166373632626539326166353965363262633030333630313338646335303630 3438626666666137650a353638643435666633633964366338633066623234616432373231333331 6564
Encrypt using vault ID 'dev' in password file:
ansible-vault encrypt_string --vault-id dev@a_password_file 'foooodev' --name 'the_dev_secret'
Encrypt as passed in:
echo -n 'letmein' | ansible-vault encrypt_string --vault-id dev@a_password_file --stdin-name 'db_password'
To view the encrypted variable in vars file:
ansible localhost -m ansible.builtin.debug -a var="new_user_password" -e "@vars.yml" --vault-id dev@a_password_file # ansible localhost -m debug -a var="new_user_password" -e "@vars.yml" --ask-vault-pass
Embedding in playbook: (not the recommended way!)
- name: Some playbook hosts: [myhosts] vars: ansible_password: !vault | $ANSIBLE_VAULT;1.1;AES256 3734356233663562...
NOTE: Note sure how to view encrypted var embedded inside a playbook??
ref: https://docs.ansible.com/ansible/latest/vault_guide/vault_encrypting_content.html
Ansible Lint
Install:
pip install ansible-lint
Use:
ansible-lint [playbook]
AWX
AWX provides a web-based user interface, REST API, and task engine built on top of Ansible. It is the upstream project for Tower, a commercial derivative of AWX.
https://github.com/ansible/awx
AWX stands for "Ansible WorX" a play on AnsibleWorks.
--
AWX in Ansible AWX stands for Ansible WorX
It is found inside this commit https://github.com/ansible/awx/commit/5c6895e6065a81f4483dfb6bc7650706f8866e1e
They used an X instead of ks
ref: https://stackoverflow.com/questions/63509580/ansible-awx-what-awx-stands-for
Galaxy Framework
Galaxy Framework Role Initalize
ansible-galaxy init [role]
Example:
ansible-galaxy init linux-common
`-- linux-common |-- README.md |-- defaults | `-- main.yml |-- files |-- handlers | `-- main.yml |-- meta | `-- main.yml |-- tasks | `-- main.yml |-- templates |-- tests | |-- inventory | `-- test.yml `-- vars `-- main.yml
See https://docs.ansible.com/ansible/latest/cli/ansible-galaxy.html#collection-init
Galaxy Community Collections
Install:
Install docker community - https://galaxy.ansible.com/ui/repo/published/community/docker/
ansible-galaxy collection install community.docker
Download:
Download docker community - https://galaxy.ansible.com/ui/repo/published/community/docker/
ansible-galaxy collection download community.docker
Downloads into "collections" folder collections/community-docker-3.12.1.tar.gz collections/community-library_inventory_filtering_v1-1.0.1.tar.gz collections/requirements.yml
Downloading https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/community-docker-3.12.1.tar.gz Downloading https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/community-library_inventory_filtering_v1-1.0.1.tar.gz requirements.yml
# cat requirements.yml collections: - name: community-docker-3.12.1.tar.gz version: 3.12.1 - name: community-library_inventory_filtering_v1-1.0.1.tar.gz version: 1.0.1
To use archive with ansible project:
ansible.cfg:
[defaults] collections_paths = collections
Extract community-docker-3.12.1.tar.gz into /collections/ansible_collections/community/docker/
Collections structure:
/collections/ /ansible_collections/ /ansible/ /posix/ /windows/ /chocolatey/ /chocolatey/ /community/ /crypto/ /docker/ /general/ /mysql/ /windows/ /devsec/ /hardening/ /kubernetes/ /core/
- name: docker_login_artifactory docker_login: registry: "{{ item }}" username: "{{ artifactory_api_username }}" password: "{{ artifactory_api_key }}" reauthorize: yes with_items: - "{{ docker_artifactory_cache }}" - "{{ docker_artifactory_registry }}" tags: - docker_login_artifactory
Sample Ansible Simple Playbook
inventory:
[webservers] server1 server2 [databases] server3 server4
playbook.yml:
--- - name: Update web servers hosts: webservers remote_user: root tasks: - name: Ensure apache is at the latest version ansible.builtin.yum: name: httpd state: latest - name: Write the apache config file ansible.builtin.template: src: /srv/httpd.j2 dest: /etc/httpd.conf - name: Update db servers hosts: databases remote_user: root tasks: - name: Ensure postgresql is at the latest version ansible.builtin.yum: name: postgresql state: latest - name: Ensure that postgresql is started ansible.builtin.service: name: postgresql state: started
Run:
ansible-playbook -i inventory playbook.yml
ref: https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html
Sample Ansible Setup
ansible.cfg inventory/ systems.ini #or systems.yml group_vars/ group1.yml host_vars/ hostname1.yml playbook1.yml # or - if do this you will need to modify the roles_path in ansible.cfg # playbooks/ # playbook1.yml roles/ role1/ .... tasks/ main.yml
ansible.cfg:
[defaults] inventory = inventory
inventory/systems: (ini format, but no .ini extension)
[linux] host1 host2
inventory/systems.yml:
linux: hosts: host1 host2
playbook1.yml:
- hosts: [linux] roles: - linux-common
roles/linux-common/tasks/main.yml:
- import_tasks: update_apt.yml
roles/linux-common/tasks/update_apt.yml:
# Ref: https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html - name: Run an apt-get update [tag - apt_update] ansible.builtin.apt: update_cache: yes tags: - apt_update - name: Run an apt-get upgrade [tag - apt_upgrade] ansible.builtin.apt: update_cache: yes upgrade: yes tags: - apt_upgrade
Run examples:
ansible-playbook playbook1.yml ansible-playbook playbook1.yml -t apt_update
See https://docs.ansible.com/ansible/latest/tips_tricks/sample_setup.html
Variable Precedence
Understanding variable precedence
Ansible does apply variable precedence, and you might have a use for it. Here is the order of precedence from least to greatest (the last listed variables override all other variables):
- command line values (for example, -u my_user, these are not variables)
- role defaults (defined in role/defaults/main.yml) 1
- inventory file or script group vars 2
- inventory group_vars/all 3
- playbook group_vars/all 3
- inventory group_vars/* 3
- playbook group_vars/* 3
- inventory file or script host vars 2
- inventory host_vars/* 3
- playbook host_vars/* 3
- host facts / cached set_facts 4
- play vars
- play vars_prompt
- play vars_files
- role vars (defined in role/vars/main.yml)
- block vars (only for tasks in block)
- task vars (only for the task)
- include_vars
- set_facts / registered vars
- role (and include_role) params
- include params
- extra vars (for example, -e "user=my_user")(always win precedence)
ref:
Using Variables — Ansible Documentation https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html