# Ansible integration

Ansible integration into Cycloid pipeline is made easier by a script provided in cycloid/cycloid-toolkit (opens new window) docker image, called ansible-runner.

Ansible runner is a wrapper of ansible-playbook command, which can be configured with several environment variables to simplify Ansible's integration into a Pipeline and provide additional functions.

A complete example of usage in a Cycloid pipeline can be found in pipelines-examples

# Standard usage

# Dynamic inventory

The ansible runner script by default will detect which cloud provider dynamic inventory (opens new window) plugins to find servers based on the environment variables you provided.

The script currently support the detection for the following dynamic inventories:

TIP

More dynamic inventories will be added to the ansible-runner in the future, but if you need one that is not yet supported, you can:

Then:

It's up to you to configure your playbook to target your instances based on exclude and include groups (opens new window) that are automatically defined by the dynamic inventory such as the cloud provider name, region or based on tags.

Now if we had to run, for example, ansible-playbook -e project=owl -e env=demo with this playbook, we could define the following hosts filter:

- hosts: tag_role_front:&tag_project_{{project}}:&tag_env_{{ env }}:!tag_packer_build_true
...
1
2

Ansible will run the playbook on instances matching the project=owl and env=demo tags but exclude those with the tag packer_build=true.

If your servers are located in a private network, ansible-runner can work with the Bastion host (opens new window) approach.

In an Amazon Web Services (AWS) context, a bastion host is defined as "instances that sit within your public subnet and are typically accessed using SSH or RDP. Once remote connectivity has been established with the bastion host, it then acts as a "jump" server, allowing you to use SSH or RDP to log in to other instances (within private subnets) deeper within your VPC. When properly configured through the use of security groups and Network ACLs (NACLs), the bastion essentially acts as a bridge to your private instances via the internet."

If you're interested, you can read more about this concept on AWS documentation:

TIP

By default the configuration of ansible-runner will use the private IP address to connect to instances. If you do not use a bastion server, you might want to add the following configuration environment variables to use public IPs:

  • Amazon EC2: AWS_EC2_COMPOSE_ANSIBLE_HOST=ip_address
  • Azure: AZURE_USE_PRIVATE_IP=False
  • GCP: GCP_USE_PRIVATE_IP=False

You can see more configuration options for the ansible-runner script here (opens new window).

Tips: If you would like to have a glimpse into how the dynamic inventory plugin or script is organizing your instances into groups, you can use the ansible-inventory command line:

run:
  path: /bin/bash
  args:
    - '-exc'
    - |
      /usr/bin/ansible-runner-inventory

      # Same way you would run the ansible runner
      # /usr/bin/ansible-runner
1
2
3
4
5
6
7
8
9

# Static inventory file

If you're not using Ansible's dynamic inventory and still want to employ our ansible-runner, you can provide a static inventory file. To do this, simply specify the location of this file using the following environment variable: ANSIBLE_INVENTORY (opens new window).

You have the flexibility to place the inventory file directly within your stack or configuration Git repository. Alternatively, you can generate it dynamically within the pipeline. Typically, in our stack examples, you'll find the file located under the following directory: ANSIBLE_INVENTORY: inventory where by default relative path refer to ANSIBLE_PLAYBOOK_PATH

# Use Cycloid credentials variables with Ansible

As described in pipeline variables the easiest way is to pass variables through the pipeline. The public Magento stack gives a good example by providing AWS credentials and SSH key to ansible runner : pipeline.yml (opens new window)

To extend a bit this example, we can create a Cycloid custom credential called mysecret with a field foo. And pass it to Ansible as variable :

Cycloid cred

Then provide an extra Ansible variables called secret_foo with EXTRA_ANSIBLE_VARS :








 

      - task: ansible-runner
        <<: *run-ansible
        params:
          SSH_PRIVATE_KEY: ((bastion_private_key_pair))
...
          AWS_SECRET_ACCESS_KEY: ((aws_secret_key))
          EXTRA_ANSIBLE_VARS:
            secret_foo: ((custom_mysecret.foo))
1
2
3
4
5
6
7
8

# Use Terraform outputs as Ansible variables

This topic is handled in variables-sharing section

# Environments variables of ansible runner

To find out more about all the environments variables you can use to configure ansible-runner, please refer to the README of the repository (opens new window).