ansible snippets

How to use Ansible Vault to store SSL certificates

Tagged ssl, certificates, ansible, vault  Languages bash

Playbook

In playbook.yml, list the file where we'll put the SSL certificates:

---
- hosts: servers
  roles:
...
  vars_files:
    - vault/certs/{{ domain }}.yml # Private SSL certificates

Ansible Vault

Next, create an encrypted Ansible vault (one per domain):

$ ansible-vault create vault/certs/xxx.com.yml

Put the following in the vault/certs/xxx.com.yml:

certificates:
  - name: "xxx.com.pem"
    content: |
      -----BEGIN CERTIFICATE-----
  - name: "login.xxx.com.pem"
    content: |
      -----BEGIN CERTIFICATE-----

The last thing we need to do is copy the certificates from the Ansible Vault to the server (roles/ssl_certs/tasks/main.yml):

- name: Copy private SSL certificates from Ansible Vault
  tags: ssl_certs
  copy:
    content: "{{ item.content }}"
    dest: "/etc/ssl/private/{{ item.name }}"
    owner: root
    group: root
    mode: "u=rw,g=r,o="
  sudo: yes
  with_items:
    # Certificates are stored encrypted in vault/certs/{{ domain }}.yml
    - "{{ certificates }}"

Usage

Use ask-vault-pass to specify the Ansible Vault's password at deployment:

$ ansible-playbook -i inventory/hosts --limit server1 --tags "ssl_certs" playbook.yml -v --ask-vault-pass

How to fix "Permission denied (publickey)." Ansible and "git clone" issue

Tagged ansible, git  Languages bash

If you have a "git clone" command like this in Ansible:

- name: Update code
  git: >
    repo={{ git_url }}
    dest={{ this_release_path }}
    version={{ git_version }}
    accept_hostkey=yes
  register: git

And the playbook is set to use sudo for all commands.

And you get this error:

stderr: Cloning into 'jeb-bush'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

FATAL: all hosts have already failed -- aborting

It could be that you need to add "sudo: no" to the task.

- name: Update code
  sudo: no
  git: >
    repo={{ git_url }}
    dest={{ this_release_path }}
    version={{ git_version }}
    accept_hostkey=yes
  register: git

How to debug Ansible variables

Tagged ansible, debug, hostvars, variables  Languages bash, yaml

Print all variables for all hosts from the command line:

 $ ansible -i inventory/local -m debug -a "var=hostvars" all

Replace hostvars with any of the following to print:

  • ansible_locals
  • groups
  • group_names
  • environment
  • vars
  • ansible_sucks

Print all variables for all hosts from a playbook:

- hosts: all
  tasks:
    -  debug:
        var: hostvars[inventory_hostname]
        # -vvv to debug !!!!
        # verbosity: 4

Print all variables:

- name: print ansible_local
  debug: var=ansible_local

Ansible: How to find the IP address of a specific network interface when there are multiple network interfaces

Tagged ansible, ip address, network  Languages yaml

Here’s how to find the IP address of a specific network interface that matches a given CIDR:

- hosts: all
  gather_facts: false
  tasks:
    - set_fact:
        prod_ip_addr: "{{ item }}"
      when: "item | ipaddr('192.168.10.0/24')"
      with_items: "{{ ansible_all_ipv4_addresses }}"
    - debug: var=prod_ip_addr

This is useful for example when you have a separate management network interface.

It’s almost as easy as trying to explain what the script is doing in plain English.

How to set the setgid flag with Ansible

Tagged ansible, setgid, setuid  Languages yaml

This is how to set the setgid flag with Ansible. Tested with Ansible version 2.4.

- name: Create directories and set setguid
  file:
    path: "{{item}}"
    state: directory
    owner: www-data
    group: www-data
    # NOTE: 2 = setguid flag. The prefix 0 is required by Ansible
    mode: 02770
    recurse: true
  with_items:
    - /var/www/
  become: true

Reference

Setting the setgid permission on a directory (“chmod g+s”) causes new files and subdirectories created within it to inherit its group ID, rather than the primary group ID of the user who created the file (the owner ID is never affected, only the group ID).

See https://en.wikipedia.org/wiki/Setuid

Detecting software version with Ansible

Tagged ansible, version  Languages yaml

With Ansible, detecting the version of, for example, Redis or Racket can be done like this:

- name: Detect Redis version
  # Input: Redis server v=3.2.1 sha=00000000:0 malloc=libc bits=64 build=62a67eec83b28403
  # Output: 3.2.1
  shell: redis-server -v | awk '{print $3}' | sed -e 's/v=//'
  changed_when: False
  register: redis_installed_version

- name: Detect racket versions
  # Input: Welcome to Racket v6.6.
  # Output: 6.6
  shell: "racket -v | rev | cut -d ' ' -f1 | rev | sed 's/.$//' | sed 's/^v//'"
  register: racket_installed_version

Example: Download src only if version does not match:

- get_url:
    url: http://download.redis.io/releases/redis-{{redis_version}}.tar.gz
    dest: /usr/local/src/
    sha256sum: "{{redis_sha256}}"
  register: get_redis_result
  when: redis_installed_version.stdout | version_compare(redis_version, '!=')