Ansible is an automation language and automation engine that lets you describe end-to-end IT application environments with a “playbook.” Ansible’s simple, human-readable language allows orchestration of your application lifecycle no matter where it’s deployed.
Conjur Ansible integration diagram
Instead of all secrets moving through the Ansible Controller, each Ansible-managed remote node is responsible using its own identity to retrieve secrets from Conjur.
The Conjur Ansible Role can be used to configure a host with Conjur machine identity. Using Conjur policy, the Ansible host can be granted least-privilege access to securely retrieve only the secrets it needs. Restricting the secrets accessible to each Ansible host reduces the administrative power of each Ansible host and prevents them from becoming high value targets. Integrating with Conjur also provides additional benefits, including storing security policy as code and simplified secret rotation.
To grant your Ansible host a Conjur identity, you first must install the Conjur Ansible Role in your playbook directly.
Ansible 2.8:
$ ansible-galaxy install cyberark.conjur-host-identity
Ansible 2.9+:
$ ansible-galaxy collection install cyberark.conjur
Once you've done this, you can configure each Ansible node with a Conjur identity by including a section like the example below in your Ansible playbook:
- hosts: servers
roles:
- role: cyberark.conjur.conjur-host-identity
conjur_appliance_url: 'https://conjur.myorg.com',
conjur_account: 'myorg',
conjur_host_factory_token: "{{ lookup('env', 'HFTOKEN') }}",
conjur_host_name: "{{ inventory_hostname }}"
conjur_ssl_certificate: "{{ lookup('file', '/path/to/conjur.pem') }}"
conjur_validate_certs: yes
Note: For Ansible 2.8 users leveraging the standalone role instead of the collection, the role should be referenced
as role: cyberark.conjur-host-identity
instead.
This example:
Registers the host with Conjur, adding it into the layer specific to the provided host factory token.
Installs Summon with the Summon Conjur provider for secret retrieval from Conjur.
For more information on the supported Conjur Role variables, please see our GitHub documentation.
When you configure the Ansible node with a Conjur identity using the Conjur Ansible Role, you also install Summon and the Summon-Conjur Provider on the Ansible host.
With Summon installed, using Conjur with a Service Manager (like SystemD
) becomes a snap. Here's a simple example of a
SystemD
file connecting to Conjur:
[Unit]
Description=DemoApp
After=network-online.target
[Service]
User=DemoUser
ExecStart=/usr/local/bin/summon --yaml 'DB_PASSWORD: !var staging/demoapp/database/password' /usr/local/bin/myapp
The above example uses Summon to retrieve the password stored in Conjur at staging/myapp/database/password
,
set it to an environment variable DB_PASSWORD
, and provide it to the demo application process. Using Summon,
the secret is kept off disk. If the service is restarted, Summon retrieves the password as the application is started.
Ansible 2.8 comes built-in with the conjur_variable
Lookup Plugin,
and when you install the collection in Ansible 2.9+ you are also installing the conjur_variable
lookup plugin. The lookup plugin can be used to retrieve secrets from Conjur using the controlling host's Conjur identity.
In general, lookup plugins allow Ansible to access data from outside sources. They can be used in a play, in a variables file, or in a Jinja2 template for the template module.
To use the conjur_variable
lookup plugin, invoke it the same way any lookup plugin is invoked.
Ansible 2.8:
vars:
database_url: "{{ lookup('conjur_variable', '/path/to/secret') }}"
Ansible 2.9+:
vars:
database_url: "{{ lookup('cyberark.conjur.conjur_variable', '/path/to/secret') }}"