Ansible integration into Cycloid pipeline is made easier by a script provided in cycloid/cycloid-toolkit 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

The ansible runner script by default will detect which cloud provider dynamic inventory script or plugin to use 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:

  • Add it by extending our cycloid/cycloid-toolkit docker image
  • Add it on the run by customizing the ansible-runner task
  • Contribute it to our ansible-runner script here

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

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'
    - |
      # ec2
      ansible-inventory -i /etc/ansible/hosts/ec2.py --graph

      # azure plugin
      ansible-inventory -i /etc/ansible/hosts/default.azure_rm.yml --graph

      # azure script
      ansible-inventory -i /etc/ansible/hosts/azure_rm_py --graph

      /usr/bin/ansible-runner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

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 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: EC2_VPC_DESTINATION_VARIABLE=ip_address
  • Azure: AZURE_USE_PRIVATE_IP=False

You can see more configuration options for the ansible-runner script here.

# Use Cycloid credentials variables with Ansible

As described in vault-in-the-pipeline 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

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.