Ansible

  • What is ansible lightspeed which showed up in vscode (lower right menu)
  • 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