mirror of
https://github.com/ansible/awx.git
synced 2026-01-09 23:12:08 -03:30
Add ldap support to vault container in docker dev environment (#14777)
* add ldap_auth mount and configure it * added in key engines, userpass auth method, still needs testing * add policies and fix ldap_user * start awx automation for vault demo and move ldap * update docs with new flags/new credentials
This commit is contained in:
parent
2e5306ae8e
commit
519fd22bec
3
Makefile
3
Makefile
@ -538,7 +538,8 @@ docker-compose: awx/projects docker-compose-sources
|
||||
ansible-galaxy install --ignore-certs -r tools/docker-compose/ansible/requirements.yml;
|
||||
ansible-playbook -i tools/docker-compose/inventory tools/docker-compose/ansible/initialize_containers.yml \
|
||||
-e enable_vault=$(VAULT) \
|
||||
-e vault_tls=$(VAULT_TLS);
|
||||
-e vault_tls=$(VAULT_TLS) \
|
||||
-e enable_ldap=$(LDAP);
|
||||
$(DOCKER_COMPOSE) -f tools/docker-compose/_sources/docker-compose.yml $(COMPOSE_OPTS) up $(COMPOSE_UP_OPTS) --remove-orphans
|
||||
|
||||
docker-compose-credential-plugins: awx/projects docker-compose-sources
|
||||
|
||||
@ -538,13 +538,15 @@ To create a secret connected to this vault in AWX you can run the following play
|
||||
```bash
|
||||
export CONTROLLER_USERNAME=<your username>
|
||||
export CONTROLLER_PASSWORD=<your password>
|
||||
ansible-playbook tools/docker-compose/ansible/plumb_vault.yml
|
||||
ansible-playbook tools/docker-compose/ansible/plumb_vault.yml -e enable_ldap=false
|
||||
```
|
||||
|
||||
This will create the following items in your AWX instance:
|
||||
* A credential called `Vault Lookup Cred` tied to the vault instance.
|
||||
* A credential called `Vault UserPass Lookup Cred` tied to the vault instance.
|
||||
* A custom credential type called `Vault Custom Cred Type`.
|
||||
* A credential called `Credential From Vault` which is of the created type using the `Vault Lookup Cred` to get the password.
|
||||
* A credential called `Credential From HashiCorp Vault via Token Auth` which is of the created type using the `Vault Lookup Cred` to get the secret.
|
||||
* A credential called `Credential From HashiCorp Vault via UserPass Auth` which is of the created type using the `Vault Userpass Lookup Cred` to get the secret.
|
||||
|
||||
The custom credential type adds a variable when used in a playbook called `the_secret_from_vault`.
|
||||
If you have a playbook like:
|
||||
@ -559,7 +561,46 @@ If you have a playbook like:
|
||||
var: the_secret_from_vault
|
||||
```
|
||||
|
||||
And run it through AWX with the credential `Credential From Vault` tied to it, the debug should result in `this_is_the_secret_value`
|
||||
And run it through AWX with the credential `Credential From Vault via Token Auth` tied to it, the debug should result in `this_is_the_secret_value`. If you run it through AWX with the credential `Credential From Vault via Userpass Auth`, the debug should result in `this_is_the_userpass_secret_value`.
|
||||
|
||||
### HashiVault with LDAP
|
||||
|
||||
If you wish to have your OpenLDAP container connected to the Vault container, you will first need to have the OpenLDAP container running alongside AWX and Vault.
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
VAULT=true LDAP=true make docker-compose
|
||||
|
||||
```
|
||||
|
||||
Similar to the above, you will need to unseal the vault before we can run the other needed playbooks.
|
||||
|
||||
```bash
|
||||
|
||||
ansible-playbook tools/docker-compose/ansible/unseal_vault.yml
|
||||
|
||||
```
|
||||
|
||||
Now that the vault is unsealed, we can plumb the vault container now while passing true to enable_ldap extra var.
|
||||
|
||||
|
||||
```bash
|
||||
|
||||
export CONTROLLER_USERNAME=<your username>
|
||||
|
||||
export CONTROLLER_PASSWORD=<your password>
|
||||
|
||||
ansible-playbook tools/docker-compose/ansible/plumb_vault.yml -e enable_ldap=true
|
||||
|
||||
```
|
||||
|
||||
This will populate your AWX instance with LDAP specific items.
|
||||
|
||||
- A vault LDAP Lookup Cred tied to the LDAP `awx_ldap_vault` user called `Vault LDAP Lookup Cred`
|
||||
- A credential called `Credential From HashiCorp Vault via LDAP Auth` which is of the created type using the `Vault LDAP Lookup Cred` to get the secret.
|
||||
|
||||
And run it through AWX with the credential `Credential From HashiCorp Vault via LDAP Auth` tied to it, the debug should result in `this_is_the_ldap_secret_value`.
|
||||
|
||||
The extremely non-obvious input is the fact that the fact prefixes "data/" unexpectedly.
|
||||
This was discovered by inspecting the secret with the vault CLI, which may help with future troubleshooting.
|
||||
|
||||
@ -34,6 +34,7 @@ ldap_cert_subject: "/C=US/ST=NC/L=Durham/O=awx/CN="
|
||||
enable_vault: false
|
||||
vault_tls: false
|
||||
hashivault_cert_dir: '{{ sources_dest }}/vault_certs'
|
||||
hashivault_vars_file: '../vault/defaults/main.yml'
|
||||
hashivault_server_cert_subject: "/C=US/ST=NC/L=Durham/O=awx/CN=tools-vault-1"
|
||||
hashivault_server_cert_extensions:
|
||||
- "subjectAltName = DNS:tools_vault_1, DNS:localhost"
|
||||
|
||||
@ -7,12 +7,15 @@
|
||||
- "{{ ldap_cert_dir }}"
|
||||
- "{{ ldap_diff_dir }}"
|
||||
|
||||
- name: include vault vars
|
||||
include_vars: "{{ hashivault_vars_file }}"
|
||||
|
||||
- name: General LDAP cert
|
||||
command: 'openssl req -new -x509 -days 365 -nodes -out {{ ldap_public_key_file }} -keyout {{ ldap_private_key_file }} -subj "{{ ldap_cert_subject }}"'
|
||||
args:
|
||||
creates: "{{ ldap_public_key_file }}"
|
||||
|
||||
- name: Copy ldap.diff
|
||||
copy:
|
||||
src: "ldap.ldif"
|
||||
ansible.builtin.template:
|
||||
src: "ldap.ldif.j2"
|
||||
dest: "{{ ldap_diff_dir }}/ldap.ldif"
|
||||
|
||||
@ -84,3 +84,16 @@ objectClass: top
|
||||
objectClass: groupOfNames
|
||||
member: cn=awx_ldap_org_admin,ou=users,dc=example,dc=org
|
||||
|
||||
{% if enable_ldap|bool and enable_vault|bool %}
|
||||
dn: cn={{ vault_ldap_username }},ou=users,dc=example,dc=org
|
||||
changetype: add
|
||||
mail: vault@example.org
|
||||
sn: LdapVaultAdmin
|
||||
cn: {{ vault_ldap_username }}
|
||||
objectClass: top
|
||||
objectClass: person
|
||||
objectClass: organizationalPerson
|
||||
objectClass: inetOrgPerson
|
||||
userPassword: {{ vault_ldap_password }}
|
||||
givenName: awx
|
||||
{% endif %}
|
||||
@ -1,7 +1,12 @@
|
||||
---
|
||||
vault_file: "{{ sources_dest }}/secrets/vault_init.yml"
|
||||
admin_password_file: "{{ sources_dest }}/secrets/admin_password.yml"
|
||||
vault_cert_dir: '{{ sources_dest }}/vault_certs'
|
||||
vault_cert_dir: "{{ sources_dest }}/vault_certs"
|
||||
vault_server_cert: "{{ vault_cert_dir }}/server.crt"
|
||||
vault_client_cert: "{{ vault_cert_dir }}/client.crt"
|
||||
vault_client_key: "{{ vault_cert_dir }}/client.key"
|
||||
ldap_ldif: "{{ sources_dest }}/ldap.ldifs/ldap.ldif"
|
||||
vault_ldap_username: "awx_ldap_vault"
|
||||
vault_ldap_password: "vault123"
|
||||
vault_userpass_username: "awx_userpass_admin"
|
||||
vault_userpass_password: "userpass123"
|
||||
|
||||
@ -92,6 +92,128 @@
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
|
||||
- name: Configure the vault ldap auth
|
||||
block:
|
||||
- name: Create ldap auth mount
|
||||
flowerysong.hvault.write:
|
||||
path: "sys/auth/ldap"
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
data:
|
||||
type: "ldap"
|
||||
register: vault_auth_ldap
|
||||
changed_when: vault_auth_ldap.result.errors | default([]) | length == 0
|
||||
failed_when:
|
||||
- vault_auth_ldap.result.errors | default([]) | length > 0
|
||||
- "'path is already in use at ldap/' not in vault_auth_ldap.result.errors | default([])"
|
||||
|
||||
- name: Create ldap engine
|
||||
flowerysong.hvault.engine:
|
||||
path: "ldap_engine"
|
||||
type: "kv"
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
|
||||
- name: Create a ldap secret
|
||||
flowerysong.hvault.kv:
|
||||
mount_point: "ldap_engine/ldaps_root"
|
||||
key: "ldap_secret"
|
||||
value:
|
||||
my_key: "this_is_the_ldap_secret_value"
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
|
||||
- name: Configure ldap auth
|
||||
flowerysong.hvault.ldap_config:
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
url: "ldap://ldap:1389"
|
||||
binddn: "cn=awx_ldap_vault,ou=users,dc=example,dc=org"
|
||||
bindpass: "vault123"
|
||||
userdn: "ou=users,dc=example,dc=org"
|
||||
deny_null_bind: "false"
|
||||
discoverdn: "true"
|
||||
|
||||
- name: Create ldap access policy
|
||||
flowerysong.hvault.policy:
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
name: "ldap_engine"
|
||||
policy:
|
||||
ldap_engine/*: [create, read, update, delete, list]
|
||||
sys/mounts:/*: [create, read, update, delete, list]
|
||||
sys/mounts: [read]
|
||||
|
||||
- name: Add awx_ldap_vault user to auth_method
|
||||
flowerysong.hvault.ldap_user:
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
state: present
|
||||
name: "{{ vault_ldap_username }}"
|
||||
policies:
|
||||
- "ldap_engine"
|
||||
when: enable_ldap | bool
|
||||
|
||||
- name: Create userpass engine
|
||||
flowerysong.hvault.engine:
|
||||
path: "userpass_engine"
|
||||
type: "kv"
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
|
||||
- name: Create a userpass secret
|
||||
flowerysong.hvault.kv:
|
||||
mount_point: "userpass_engine/userpass_root"
|
||||
key: "userpass_secret"
|
||||
value:
|
||||
my_key: "this_is_the_userpass_secret_value"
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
|
||||
- name: Create userpass access policy
|
||||
flowerysong.hvault.policy:
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
name: "userpass_engine"
|
||||
policy:
|
||||
userpass_engine/*: [create, read, update, delete, list]
|
||||
sys/mounts:/*: [create, read, update, delete, list]
|
||||
sys/mounts: [read]
|
||||
|
||||
- name: Create userpass auth mount
|
||||
flowerysong.hvault.write:
|
||||
path: "sys/auth/userpass"
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
data:
|
||||
type: "userpass"
|
||||
register: vault_auth_userpass
|
||||
changed_when: vault_auth_userpass.result.errors | default([]) | length == 0
|
||||
failed_when:
|
||||
- vault_auth_userpass.result.errors | default([]) | length > 0
|
||||
- "'path is already in use at userpass/' not in vault_auth_userpass.result.errors | default([])"
|
||||
|
||||
- name: Add awx_userpass_admin user to auth_method
|
||||
flowerysong.hvault.write:
|
||||
vault_addr: "{{ vault_addr_from_host }}"
|
||||
validate_certs: false
|
||||
token: "{{ Initial_Root_Token }}"
|
||||
path: "auth/userpass/users/{{ vault_userpass_username }}"
|
||||
data:
|
||||
password: "{{ vault_userpass_password }}"
|
||||
policies:
|
||||
- "userpass_engine"
|
||||
|
||||
always:
|
||||
- name: Stop the vault
|
||||
community.docker.docker_compose:
|
||||
|
||||
@ -38,7 +38,6 @@
|
||||
controller_host: "{{ awx_host }}"
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_password }}"
|
||||
|
||||
validate_certs: false
|
||||
injectors:
|
||||
extra_vars:
|
||||
@ -51,28 +50,26 @@
|
||||
secret: true
|
||||
register: custom_vault_cred_type
|
||||
|
||||
- name: Create a credential of the custom type
|
||||
- name: Create a credential of the custom type for token auth
|
||||
awx.awx.credential:
|
||||
credential_type: "{{ custom_vault_cred_type.id }}"
|
||||
controller_host: "{{ awx_host }}"
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_password }}"
|
||||
|
||||
validate_certs: false
|
||||
name: Credential From Vault
|
||||
name: Credential From HashiCorp Vault via Token Auth
|
||||
inputs: {}
|
||||
organization: Default
|
||||
register: custom_credential
|
||||
register: custom_credential_via_token
|
||||
|
||||
- name: Use the Vault Credential For the new credential
|
||||
- name: Use the Token Vault Credential For the new credential
|
||||
awx.awx.credential_input_source:
|
||||
input_field_name: password
|
||||
target_credential: "{{ custom_credential.id }}"
|
||||
target_credential: "{{ custom_credential_via_token.id }}"
|
||||
source_credential: "{{ vault_cred.id }}"
|
||||
controller_host: "{{ awx_host }}"
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_password }}"
|
||||
|
||||
validate_certs: false
|
||||
metadata:
|
||||
auth_path: ""
|
||||
@ -80,3 +77,100 @@
|
||||
secret_key: "my_key"
|
||||
secret_path: "/my_root/my_folder"
|
||||
secret_version: ""
|
||||
|
||||
- name: Create a HashiCorp Vault Credential for LDAP
|
||||
awx.awx.credential:
|
||||
credential_type: HashiCorp Vault Secret Lookup
|
||||
name: Vault LDAP Lookup Cred
|
||||
organization: Default
|
||||
controller_host: "{{ awx_host }}"
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_password }}"
|
||||
validate_certs: false
|
||||
inputs:
|
||||
api_version: "v1"
|
||||
default_auth_path: "ldap"
|
||||
kubernetes_role: ""
|
||||
namespace: ""
|
||||
url: "{{ vault_addr_from_container }}"
|
||||
username: "{{ vault_ldap_username }}"
|
||||
password: "{{ vault_ldap_password }}"
|
||||
register: vault_ldap_cred
|
||||
when: enable_ldap | bool
|
||||
|
||||
- name: Create a credential from the Vault LDAP Custom Cred Type
|
||||
awx.awx.credential:
|
||||
credential_type: "{{ custom_vault_cred_type.id }}"
|
||||
controller_host: "{{ awx_host }}"
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_password }}"
|
||||
validate_certs: false
|
||||
name: Credential From HashiCorp Vault via LDAP Auth
|
||||
inputs: {}
|
||||
organization: Default
|
||||
register: custom_credential_via_ldap
|
||||
when: enable_ldap | bool
|
||||
|
||||
- name: Use the Vault LDAP Credential the new credential
|
||||
awx.awx.credential_input_source:
|
||||
input_field_name: password
|
||||
target_credential: "{{ custom_credential_via_ldap.id }}"
|
||||
source_credential: "{{ vault_ldap_cred.id }}"
|
||||
controller_host: "{{ awx_host }}"
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_password }}"
|
||||
validate_certs: false
|
||||
metadata:
|
||||
auth_path: ""
|
||||
secret_backend: "ldap_engine"
|
||||
secret_key: "my_key"
|
||||
secret_path: "ldaps_root/ldap_secret"
|
||||
secret_version: ""
|
||||
when: enable_ldap | bool
|
||||
|
||||
- name: Create a HashiCorp Vault Credential for UserPass
|
||||
awx.awx.credential:
|
||||
credential_type: HashiCorp Vault Secret Lookup
|
||||
name: Vault UserPass Lookup Cred
|
||||
organization: Default
|
||||
controller_host: "{{ awx_host }}"
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_password }}"
|
||||
validate_certs: false
|
||||
inputs:
|
||||
api_version: "v1"
|
||||
default_auth_path: "userpass"
|
||||
kubernetes_role: ""
|
||||
namespace: ""
|
||||
url: "{{ vault_addr_from_container }}"
|
||||
username: "{{ vault_userpass_username }}"
|
||||
password: "{{ vault_userpass_password }}"
|
||||
register: vault_userpass_cred
|
||||
|
||||
- name: Create a credential from the Vault UserPass Custom Cred Type
|
||||
awx.awx.credential:
|
||||
credential_type: "{{ custom_vault_cred_type.id }}"
|
||||
controller_host: "{{ awx_host }}"
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_password }}"
|
||||
validate_certs: false
|
||||
name: Credential From HashiCorp Vault via UserPass Auth
|
||||
inputs: {}
|
||||
organization: Default
|
||||
register: custom_credential_via_userpass
|
||||
|
||||
- name: Use the Vault UserPass Credential the new credential
|
||||
awx.awx.credential_input_source:
|
||||
input_field_name: password
|
||||
target_credential: "{{ custom_credential_via_userpass.id }}"
|
||||
source_credential: "{{ vault_userpass_cred.id }}"
|
||||
controller_host: "{{ awx_host }}"
|
||||
controller_username: admin
|
||||
controller_password: "{{ admin_password }}"
|
||||
validate_certs: false
|
||||
metadata:
|
||||
auth_path: ""
|
||||
secret_backend: "userpass_engine"
|
||||
secret_key: "my_key"
|
||||
secret_path: "userpass_root/userpass_secret"
|
||||
secret_version: ""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user