Using Containers for Day 2 Operations

There is no shortage of material discussing deployment applications in containers. They’re small, lightweight, and a completely self-contained environment purpose built for running your application.

Those same features – in particular the purpose-built environment – makes containers excellent for performing Day 2 operations functions. Load your tools into a container customised specifically for them, then administer your application or environment.

In this blog post I’ll show you one technique – we’ll build a container using Buildah, copying in some playbooks, run it using Podman, mounting in a vault password, then execute the playbooks.

Read more “Using Containers for Day 2 Operations”

OpenStack Heat vs Ansible

You’ve almost certainly heard of Ansible – the uber-simple IT automation engine developed by Red Hat. Perhaps you’ve also heard of OpenStack Heat, the orchestration engine built into the OpenStack platform.

In this post I’m going to try and summarise the major differences between these two technologies (and there are many). Mostly, however, I’m aiming to show how these two fantastic technologies can be combined to enable powerful, flawless orchestration and configuration of infrastructure deployed on OpenStack.

Read more “OpenStack Heat vs Ansible”

Rebooting a host with Ansible using reboot hints

The need to configure a host, reboot it if needed, then wait for it return, is an extremely common pattern in Ansible – so common it will (finally!) become the reboot module in Ansible 2.7.

For those of us using Ansible 2.6 or earlier, we need a way to reboot a host. There’s no shortage of suggestions out there and mine below hopes to add to those. The method I propose will:

  1. Verify if a reboot is required (using /bin/needs-restarting – CentOS/RHEL only).
  2. If necessary, reboot the host.
  3. Wait for SSH to disappear, meaning the host has progressed far into its reboot process.
  4. Wait for SSH to return, meaning the host is alive and ready for the play to continue.

Read more “Rebooting a host with Ansible using reboot hints”

Ansible, SSH jump hosts and multiple private keys

Today I ran into a situation where I was using a bastion to access instances in a private OpenStack tenancy. I wanted to use Ansible to manage these hosts, but I also wanted to do the development work on my laptop, rather than the bastion.

The problem I had was this: I wanted Ansible to use my private key on my laptop (host A) to access the jump host (host B), but then I wanted to use a private key of a user on the jump host to access the target.

The solution came from this Github post: https://serverfault.com/questions/337274/ssh-from-a-through-b-to-c-using-private-key-on-b

There are two pre-requisites for the jump host:

  1. The nmap-ncat package must be installed.
  2. The AllowAgentForwarding option in /etc/ssh/sshd_config must be “Yes”

Once I had nc installed on host B, I then set the following variable in my group_vars for the hosts I wanted to manage:

ansible_ssh_common_args: '-o ProxyCommand="ssh -o ''ForwardAgent yes'' centos@192.168.0.97 ''ssh-add && nc %h %p''"'

(For more information about jump hosts and Ansible, see the FAQ).

This setup performs the following steps:

  1. Exposes the SSH agent running on host A (my laptop) to host B through the ForwardAgent yes option. The SSH agent is responsible for keeping your private keyfile in memory so you don’t need to enter your password all the time.
  2. We execute ssh-add on host B which adds the private keys for the centos user on host B to the forwarded SSH agent. At this time the keys for the centos user on host B are now available on my laptop in my SSH agent.
  3. nc then establishes a connection to SSH on the target (host C), and the SSH client on my laptop can now negotiate the final connection as the key from host B is available in the agent.

We now have a connection to host C, and:

[agoossen@agoossen cf-ansible]$ ansible -i hosts/cloudforms all -m ping -f 1
10.0.0.19.nip.io | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
10.0.0.16.nip.io | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

Presto!