Ansible
- What is ansible lightspeed which showed up in vscode (lower right menu)
command line tools
ansible-vault
ansible-vault encrypt somefile.yml ansible-playbook --ask-vault-pass ...
Config and setup
- ansible.cfg file
- Config - see generating a config file
ansible-config list ansible-config init |t ansible-doc -l alias ac='ansible-config' alias ap='ansible-playbook' alias av='ansible-vault'- ansible.cfg file
Using Ansible Playbooks
Working with Playbooks
pre_task
Article with good example
--- - name: Install and Launch the Simple NodeJS Application hosts: testserver vars_files: - gitsecrets.yml vars: - destdir: /apps/sampleapp pre_tasks: - name : install dependencies before starting become: yes register: aptinstall apt: name: - nodejs - npm - git state: latest update_cache: yes - name : validate the nodejs installation debug: msg="Installation of node is Successfull" when: aptinstall is changed tasks: - name: Version of Node and NPM shell: "npm -v && nodejs -v" register: versioninfo - name: Validate if the installation is intact assert: that: "versioninfo is changed" - name: Create Dest Directory if not exists become: yes file: path: "{{ destdir }}" state: directory owner: vagrant group: vagrant mode: 0755 - name: Download the NodeJS code from the GitRepo become: yes git: repo: 'https://{{gittoken}}@github.com/AKSarav/SampleNodeApp.git' dest: "{{ destdir }}" - name: Change the ownership of the directory become: yes file: path: "{{destdir}}" owner: "vagrant" register: chgrpout - name: Install Dependencies with NPM install command shell: "npm install" args: chdir: "{{ destdir }}" register: npminstlout - name: Debug npm install command debug: msg='{{npminstlout.stdout_lines}}' - name: Start the App async: 10 poll: 0 shell: "(node index.js > nodesrv.log 2>&1 &)" args: chdir: "{{ destdir }}" register: appstart - name: Validating the port is open tags: nodevalidate wait_for: host: "localhost" port: 5000 delay: 10 timeout: 30 state: started msg: "NodeJS server is not running" post_tasks: - name: notify Slack that the servers have been updated tags: slack community.general.slack: token: T026******PF/B02U*****N/WOa7r**********Ao0jnWn msg: | ### StatusUpdate ### – ------------------------------------ `` `Server`: {{ansible_host}} `Status`: NodeJS Sample Application installed successfully – ------------------------------------ channel: '#ansible' color: good username: 'Ansible on {{ inventory_hostname }}' link_names: 0 parse: 'none' delegate_to: localhost
ansible.builtin.* - list
ansible.builtin.find
# example of find ansible.builtin.find: paths: ~ubuntu/backups/database patterns: '*some.dump' recurse: no age: -5d age_stamp: ctime file_type: file register: found_files_backend
- ansible.builtin.assemble - build up config files
Docs and Learning
- https://github.com/geerlingguy/ansible-for-devops - Jeff Geerling
Galaxy Jump Starts — library of roles and collections
- https://beta-galaxy.ansible.com/ui/ - 2023-08 New UI
# role template ansible-galaxy role init newrolename # install role from galaxy repo ansible-galaxy install -r localfile.yml # localfile.yml see docs for using urls and such - src: role.name version: 1.2.3
HowTo
Save content of command
- name: Retrieve the list of home directories ansible.builtin.command: ls /home register: home_dirs - name: Add home dirs to the backup spooler ansible.builtin.file: path: /mnt/bkspool/{{ item }} src: /home/{{ item }} state: link loop: "{{ home_dirs.stdout_lines }}"
AWX / Tower / Automation Controller
- AWX on k3s - best install
- AWX on k3s - interesting
- Ansible AWX deployment with playbooks
Learning
Invoke Snipets
# direnv .envrc layout python pip install --upgrade pip pip install ansible asdf reshim export ANSIBLE_INVENTORY=ansible-farm-inv.yml ansible --list-hosts all ansible --list-hosts somegroupname ansible -i ansible.inv all -m ping ansible-playbook -i ansible.inv ../../../../ansible/host-setup.yml ansible <hostname> -m ansible.builtin.setup ansible -m setup
Example tasks
--- private: yes use_hostnames: true - name: call a role ansible.builtin.include_role: name: some_role - name: Print all available facts ansible.builtin.debug: var: ansible_facts - name: Print variable ansible.builtin.debug: var: asdf - name: Example Assert ansible.builtin.assert: that: ansible_memtotal_mb > {{ mem_min }} fail_msg: "Not enough memory" success_msg: "Enough memory" - name: loop on dirs when: "'3' in item" ansible.builtin.copy: dest: "{{ item }}/somefile.txt content: "This goes in the file" loop: "{{ dir_list }} - name: capture ls out ansible.builtin.shell: "ls -l {{ item }}" loop: "{{ dir_list }}" register: ls_out changed_when: false - name: print result when: item.stdout | length > 8 ansible.builtin.debug: var: item.stdout loop: "{{ ls_out.results }}"
Role Layout
# cd roles and run ansible-galaxy init rolename roles/somerole/ defaults/ files/ templates/ handlers/ main.yml meta/ main.yml tasks/ main.yml vars/ main.yml tests/ inventory test.yml
Inventory in YAML
lab: hosts: xx.gg.com: yy.gg.com: ansible_user: ubuntu vars: ansible_user: uu ansible_python_interpreter: /usr/bin/python3 local: hosts: localhost: ansible_connection: local ansible_python_interpreter: "{{ lookup('pipe','which python3') }}"
ansible.cfg
[defaults] # (pathlist) Comma-separated list of Ansible inventory sources inventory=ansible-inv.yml # vault_password_file=./ansible-vault-pass
base setup
in templates/ckup
#!/bin/bash apt update apt list --upgradable
playbook-base-setup.yml
--- - name: Base setup for EC2 instance hosts: all become: yes tasks: - name: Update apt cache ansible.builtin.apt: update_cache: yes - name: Update and upgrade all packages to the latest version # move this to another playbook? ansible.builtin.apt: update_cache: true upgrade: dist cache_valid_time: 3600 - name: Install required packages ansible.builtin.apt: # adjust this list name: - unzip - curl - direnv - mc - jq - wget - python3-pip state: present - name: Set hostname when: newhostname is defined ansible.builtin.hostname: name: "{{ newhostname }}" - name: Ensure aliases are present in ~/.bashrc ansible.builtin.blockinfile: path: /home/{{ ansible_user }}/.bashrc block: | alias d='docker' alias dc='docker compose' alias dcl='dc logs -f --tail=0' alias dps='docker ps --format "table {{ '{{' }}.ID{{ '}}' }}\t{{ '{{' }}.State{{ '}}' }}\t{{ '{{' }}.Names{{ '}}' }}\t{{ '{{' }}.Ports{{ '}}' }}"' alias g='git' alias t='less' create: yes - name: Ensure aliases are present in /root/.bashrc ansible.builtin.blockinfile: path: /root/.bashrc block: | alias d='docker' alias dc='docker compose' alias dcl='dc logs -f --tail=0' alias dps='docker ps --format "table {{ '{{' }}.ID{{ '}}' }}\t{{ '{{' }}.State{{ '}}' }}\t{{ '{{' }}.Names{{ '}}' }}\t{{ '{{' }}.Ports{{ '}}' }}"' alias g='git' alias t='less' create: yes - name: create package check up script ansible.builtin.template: src="ckup" dest="/root/ckup" mode=0700 force=yes
Notes
# Jeff block, error, always # Usage ssh -F ./ssh.cfg h1 # check ssh ansible -i host.inv all -m ping # check ansible connections ansible-playbook -i host.inv ansible/setup.yml # run ansible
Debugging
ansible-playbook -C -i ansible.inv ../ansible/host-setup.yml --list-tasks ansible-playbook -C -i ansible.inv ../ansible/host-setup.yml -t tagname ansible-playbook -C -i ansible.inv ../ansible/host-setup.yml -t tagname -vvv
Terraform setup
# ============================================================================= # Ansible data "template_file" "inv" { template = file("${path.module}/ansible/inventory.tpl") vars = { host = aws_instance.inst1.private_ip ansible_user = local.ansible_user } } resource "local_file" "ansible-inventory" { content = data.template_file.inv.rendered filename = "${path.module}/host.inv" } data "template_file" "ssh" { template = file("${path.module}/ansible/ssh-config.tpl") vars = { private_ip = aws_instance.inst1.private_ip fqdn = "${local.hostname}.${local.domain}" ansible_user = local.ansible_user ansible_ssh_key = local.ansible_key bastion_id = local.ansible_bastion } } resource "local_file" "ssh-config" { content = data.template_file.ssh.rendered filename = "${path.module}/ssh.cfg" }
inventory.tpl
[hostgroup1] ${host} [all:vars] ansible_ssh_user=${ansible_user} ansible_ssh_common_args='-F ssh.cfg'
ssh-config.tpl
Host ${private_ip} ${fqdn} h1 HostName ${private_ip} User ${ansible_user} IdentityFile ${ansible_ssh_key} ProxyCommand ssh ${bastion_id} -W %h:%p -q