main.yml
This is where all magic happens, all steps:
rhaap base config:
- checkout rhaap base configuration
- create organization
- create organization admin
- create LDAP mappings
- add hub credentials to organization
- push changes and start merge
- wait for the pipeline to finish
organization config:
- create repository
- clone empty repository
- create branches
- create directories/files
- add pipeline
- protect branches
- push and merge
- wait for the pipeline to finish
- add the organization to recovery
There are some very complex tasks in this playbook, know your syntax well when changing!
---
# Complete rewrite for 2.6 wth external vault (Openbao/HashiCorp)
#
- name: Add Org_admin to AAP platform
hosts: localhost
gather_facts: true
pre_tasks:
- name: Get vars
ansible.builtin.include_vars: env_vars.yml
no_log: true
tasks:
# Add the organization namespace to vault
- name: Create namespace (organization_short_name) for each environment
ansible.builtin.include_tasks:
file: vault_create_namespace.yml
vars:
main_ns_name: "{{ venv.key }}"
sub_ns_name: "{{ organization_short_name | lower }}"
loop: "{{ aap_env | dict2items }}"
loop_control:
loop_var: venv
- name: Add the rhaap_admin (CaC_admin_ORG) in namespaces
ansible.builtin.include_tasks:
file: vault_create_secret.yml
vars:
secret_name: rhaap_admin
main_ns_name: "{{ wenv.key }}"
sub_ns_name: "{{ organization_short_name | lower }}"
org_admin_user: "CaC_admin_{{ organization_short_name | upper }}"
rhaap_hostname: "{{ aap_env[main_ns_name]['rhaap_hostname'] }}"
loop: "{{ aap_env | dict2items }}"
loop_control:
loop_var: wenv
- name: Add the user to base_users in all namespaces/base
ansible.builtin.include_tasks:
file: vault_add_key_to_base_users.yml
vars:
main_ns_name: "{{ senv.key }}"
sub_ns_name: base
new_key: "CaC_admin_{{ organization_short_name | upper }}"
new_value: "{{ team_password }}"
loop: "{{ aap_env | dict2items }}"
loop_control:
loop_var: senv
# Start rhaap configuration
# clone the rhaap_base repository and add things for the new organization
- name: GitLab Post | Obtain Access Token
ansible.builtin.include_tasks:
file: get_gitlab_api_token.yml
- name: Clone the GitLab repository # noqa: command-instead-of-module
ansible.builtin.shell: |
git config --global user.name "{{ gitlab_user_username }}"
git config --global user.email "{{ gitlab_user_username }}@homelab.wf"
git config --global http.sslVerify "false"
git clone "{{ gitlab_protocol }}oauth:{{ token }}@{{ gitlab_url }}{{ gitlab_group }}/{{ cac_project_name }}.git"
args:
chdir: /tmp
changed_when: true
no_log: false
- name: Create the Organization
ansible.builtin.blockinfile:
path: "/tmp/{{ cac_project_name }}/group_vars/all/aap_organizations.yml"
insertbefore: ...
marker: "# {mark} ANSIBLE MANAGED BLOCK {{ organization_long_name | upper }}"
marker_begin: "# BEGIN BLOCK {{ organization_long_name | upper }}"
marker_end: "# END BLOCK {{ organization_long_name | upper }}"
block: |
{% filter indent(width=2, first=true) %}
- name: {{ organization_long_name | upper }}
description: Organization for team {{ organization_short_name | upper }}
{% endfilter %}
- name: Make the user ORG_ADMIN
ansible.builtin.blockinfile:
path: "/tmp/{{ cac_project_name }}/group_vars/all/gateway_role_user_assignments.yml"
insertbefore: ...
marker: "# {mark} ANSIBLE MANAGED BLOCK {{ organization_long_name | upper }}"
marker_begin: "# BEGIN BLOCK {{ organization_long_name | upper }}"
marker_end: "# END BLOCK {{ organization_long_name | upper }}"
block: |
{% filter indent(width=2, first=true) %}
- role_definition: Organization Admin
user: CaC_admin_{{ organization_short_name | upper }}
object_ids: {{ organization_long_name | upper }}
{% endfilter %}
- name: Set ldap facts
ansible.builtin.set_fact:
ldap_pre: "{{ ldap | selectattr('name', 'match', ldap_name) | map(attribute='ldap_pre_str') | join() }}"
ldap_post: "{{ ldap | selectattr('name', 'match', ldap_name) | map(attribute='ldap_post_str') | join() }}"
when: add_ldap
- name: "Add a block of text to the file gateway_authenticator_maps.yml" # noqa: name[template]
ansible.builtin.blockinfile:
path: "/tmp/{{ cac_project_name }}/group_vars/all/gateway_authenticator_maps.yml"
block: |
{% filter indent(width=2, first=true) %}
- name: {{ organization_long_name | upper }}-members
authenticator: {{ ldap_name }}
revoke: true
map_type: organization
organization: {{ organization_long_name | upper }}
role: Organization Member
triggers:
groups:
has_or:
- cn={{ ldap_pre }}{{ organization_short_name }}-a{{ ldap_post }}
- cn={{ ldap_pre }}{{ organization_short_name }}-d{{ ldap_post }}
- cn={{ ldap_pre }}{{ organization_short_name }}-o{{ ldap_post }}
- name: {{ organization_long_name | upper }}-admins
authenticator: {{ ldap_name }}
revoke: true
map_type: organization
organization: {{ organization_long_name | upper }}
role: Organization Admin
triggers:
groups:
has_and:
- cn={{ ldap_pre }}{{ organization_short_name }}-a{{ ldap_post }}
- name: {{ organization_long_name | upper }}-admin-team
authenticator: {{ ldap_name }}
revoke: true
map_type: role
organization: {{ organization_long_name | upper }}
team: LDAP_{{ organization_short_name | upper }}_Admins
role: Team Member
triggers:
groups:
has_and:
- cn={{ ldap_pre }}{{ organization_short_name }}-a{{ ldap_post }}
- name: {{ organization_long_name | upper }}-developers
authenticator: {{ ldap_name }}
revoke: true
map_type: role
organization: {{ organization_long_name | upper }}
team: LDAP_{{ organization_short_name | upper }}_Developers
role: Team Member
triggers:
groups:
has_and:
- cn={{ ldap_pre }}{{ organization_short_name }}-d{{ ldap_post }}
- name: {{ organization_long_name | upper }}-operators
authenticator: {{ ldap_name }}
revoke: true
map_type: role
organization: {{ organization_long_name | upper }}
team: LDAP_{{ organization_short_name | upper }}_Operators
role: Team Member
triggers:
groups:
has_and:
- cn={{ ldap_pre }}{{ organization_short_name }}-o{{ ldap_post }}
{% endfilter %}
marker: "# {mark} ANSIBLE MANAGED BLOCK {{ organization_short_name | upper }} TEAM_MAP"
marker_begin: "# BEGIN ANSIBLE MANAGED BLOCK {{ organization_short_name | upper }}"
marker_end: "# END ANSIBLE MANAGED BLOCK {{ organization_short_name | upper }}"
backup: false
insertbefore: ...
when: add_ldap
- name: "Add a block of text to the file aap_teams.yml" # noqa: name[template]
ansible.builtin.blockinfile:
path: "/tmp/{{ cac_project_name }}/group_vars/all/aap_teams.yml"
block: |
{% filter indent(width=2, first=true) %}
- name: LDAP_{{ organization_short_name | upper }}_Admins
organization: {{ organization_long_name | upper }}
description: Organization Admins (LDAP)
- name: LDAP_{{ organization_short_name | upper }}_Developers
organization: {{ organization_long_name | upper }}
description: Organization Developers (LDAP)
- name: LDAP_{{ organization_short_name | upper }}_Operators
organization: {{ organization_long_name | upper }}
description: Organization Operators (LDAP)
{% endfilter %}
marker: "# {mark} ANSIBLE MANAGED BLOCK {{ organization_short_name | upper }} ORGANIZATION_MAP"
marker_begin: "# BEGIN ANSIBLE MANAGED BLOCK {{ organization_short_name | upper }}"
marker_end: "# END ANSIBLE MANAGED BLOCK {{ organization_short_name | upper }}"
backup: false
insertbefore: ...
when: add_ldap
# End gateway configuration, we now need to push the updates and run the pipeline
# for the development environment.
# Lets add things to the controller base configuration, before we create the config as code repository
# for the new team/organization
- name: "Add a block of text to the file controller_organizations.yml" # noqa: name[template]
ansible.builtin.blockinfile:
path: "/tmp/{{ cac_project_name }}/group_vars/all/controller_organizations.yml"
block: |
{% filter indent(width=2, first=true) %}
- name: {{ organization_long_name | upper }}
galaxy_credentials:
- MGT_automation_hub_token_community
- MGT_automation_hub_token_rh_certified
- MGT_automation_hub_token_published
- MGT_automation_hub_token_validated
{% endfilter %}
marker: "# {mark} ANSIBLE MANAGED BLOCK {{ organization_short_name | upper }} ORGANIZATION_CREDS"
marker_begin: "# BEGIN ANSIBLE MANAGED BLOCK {{ organization_short_name | upper }}"
marker_end: "# END ANSIBLE MANAGED BLOCK {{ organization_short_name | upper }}"
backup: false
insertbefore: ...
- name: "Add the organization to shared credentials in controller_roles.yml" # noqa: name[template]
ansible.builtin.lineinfile:
path: "/tmp/{{ cac_project_name }}/group_vars/all/controller_roles.yml"
line: " - {{ organization_long_name | upper }}"
backup: false
firstmatch: true
insertafter: "^ - organizations:"
- name: "Add the new teams to shared inventory in controller_roles.yml" # noqa: name[template]
ansible.builtin.blockinfile:
path: "/tmp/{{ cac_project_name }}/group_vars/all/controller_roles.yml"
block: |
{% filter indent(width=2, first=true) %}
- LDAP_{{ organization_short_name | upper }}_Admins
- LDAP_{{ organization_short_name | upper }}_Developers
{% endfilter %}
backup: false
insertafter: "^ teams:"
# End of controller base configuration for team addition
# Now run the pipeline for the development environment.
- name: Push the updated GitLab repository # noqa: command-instead-of-module
ansible.builtin.shell: |
git config --global user.name "{{ gitlab_user_username }}"
git config --global user.email "{{ gitlab_user_username }}@homelab.wf"
git add --all
git commit -m "Organization branch addition for {{ organization_long_name | upper }}"
git push origin "{{ gitlab_default_branch }}"
args:
chdir: "/tmp/{{ cac_project_name }}"
changed_when: false
no_log: false
- name: Delete the tempory directory
ansible.builtin.file:
path: /tmp/{{ cac_project_name }}
state: absent
- name: Wait for 10 secs
ansible.builtin.pause:
seconds: 10
- name: GitLab Post | Obtain Access Token
ansible.builtin.include_tasks:
file: get_gitlab_api_token.yml
- name: Create correct url for gitlab_group
ansible.builtin.set_fact:
gitlab_group_safe: "{{ gitlab_group | replace('/', '%2F') }}"
- name: Check the pipeline until it has run
ansible.builtin.uri:
url: "{{ gitlab_protocol }}{{ gitlab_url }}api/v4/projects/{{ gitlab_group_safe }}%2F{{ cac_project_name }}/jobs"
validate_certs: false
headers:
Authorization: "Bearer {{ token }}"
register: _jobs_list
failed_when: _jobs_list.json[0].pipeline.status == "failed"
until: (_jobs_list.json[0].pipeline.status == "success") or (_jobs_list.json[0].pipeline.status == "failed")
retries: 20
delay: 20
# Rhaap base configuration complete
# Now start creating the team controlled config as code repository
- name: Create GitLab Project in group
community.general.gitlab_project:
api_url: "{{ gitlab_protocol }}{{ gitlab_url }}"
validate_certs: "{{ gitlab_validate_certs }}"
api_username: "{{ gitlab_user_username }}"
api_password: "{{ gitlab_user_password }}"
name: "{{ team_project_name }}"
group: "{{ gitlab_group }}"
default_branch: "{{ gitlab_default_branch }}"
shared_runners_enabled: true
only_allow_merge_if_pipeline_succeeds: true
ci_config_path: "{{ gitlab_cac_pipeline }}"
squash_option: never
initialize_with_readme: true
state: present
- name: Create the environment branches on repository
community.general.gitlab_branch:
api_url: "{{ gitlab_protocol }}{{ gitlab_url }}"
validate_certs: "{{ gitlab_validate_certs }}"
api_username: "{{ gitlab_user_username }}"
api_password: "{{ gitlab_user_password }}"
project: "{{ gitlab_group }}/{{ team_project_name }}"
branch: "{{ curr_env }}"
ref_branch: "{{ gitlab_default_branch }}"
state: present
vars:
curr_env: "{{ cenv.key }}"
loop: "{{ aap_env | dict2items }}"
loop_control:
loop_var: cenv
- name: Set vault_secret CI/CD variables
community.general.gitlab_project_variable:
api_url: "{{ gitlab_protocol }}{{ gitlab_url }}"
validate_certs: "{{ gitlab_verify_ssl }}"
api_username: "{{ gitlab_user_username }}"
api_password: "{{ gitlab_user_password }}"
project: "{{ gitlab_group }}/{{ team_project_name }}"
purge: false
variables:
- name: ORG_NAME
value: "{{ organization_short_name | lower }}"
masked: false
protected: true
environment_scope: '*'
- name: Clone the new gitlab repository # noqa: command-instead-of-module
ansible.builtin.shell: |
git config --global user.name "{{ gitlab_user_username }}"
git config --global user.email "{{ gitlab_user_username }}@homelab.wf"
git config --global http.sslVerify "false"
git clone "{{ gitlab_protocol }}oauth:{{ token }}@{{ gitlab_url }}{{ gitlab_group }}/{{ team_project_name }}.git"
args:
chdir: /tmp
changed_when: true
no_log: true
- name: Get other vars
ansible.builtin.include_vars:
file: other_vars.yml
- name: Checkout the branch to push # noqa: command-instead-of-module
ansible.builtin.shell: |
git config --global user.name "{{ gitlab_user_username }}"
git config --global user.email "{{ gitlab_user_username }}@homelab.wf"
git config --global http.sslVerify "false"
git checkout -b initial
args:
chdir: "/tmp/{{ team_project_name }}"
changed_when: true
- name: Create the list with envs
ansible.builtin.set_fact:
env_list: |-
[
{%- for env in code_environment_vars -%}
'{{ env }}'
{%- if not loop.last -%},{%- endif -%}
{%- endfor -%}
]
- name: Create group_var directories
ansible.builtin.file:
path: "/tmp/{{ team_project_name }}/group_vars/{{ curr_env }}"
state: directory
mode: '0755'
loop: "{{ env_list }}"
loop_control:
loop_var: curr_env
- name: Create host_var directories
ansible.builtin.file:
path: "/tmp/{{ team_project_name }}/host_vars/aap_{{ curr_env }}"
state: directory
mode: '0755'
loop: "{{ env_list }}"
loop_control:
loop_var: curr_env
when: curr_env != 'all'
- name: Template the pipeline inventory
ansible.builtin.template:
src: repo_inventory.yaml.j2
dest: "/tmp/{{ team_project_name }}/inventory.yaml"
mode: "0644"
- name: Place the README.md
ansible.builtin.copy:
src: README.md
dest: "/tmp/{{ team_project_name }}/README.md"
mode: "0644"
- name: Template the aap_env.yml
ansible.builtin.template:
src: aap_env.yml.j2
dest: "/tmp/{{ team_project_name }}/host_vars/aap_{{ curr_env1 }}/aap_{{ curr_env1 }}.yaml"
mode: "0644"
loop: "{{ env_list }}"
loop_control:
loop_var: curr_env1
when: curr_env1 != 'all'
- name: Copy the main.yml playbook
ansible.builtin.copy:
src: main.yml.txt
dest: "/tmp/{{ team_project_name }}/main.yml"
mode: "0644"
- name: Create the list of templates
ansible.builtin.set_fact:
template_files:
- controller_credential_input_sources
- controller_credentials
- controller_hosts
- controller_inventories
- controller_inventory_sources
- controller_labels
- controller_notifications
- controller_projects
- controller_roles
- controller_schedules
- controller_templates
- controller_workflows
- name: Create the loop var
ansible.builtin.set_fact:
template_loop: |-
[
{%- for env in code_environment_vars -%}
{%- for file in template_files -%}
'{{ env }},{{ file }}'
{%- if not loop.last -%},
{%- endif -%}
{%- endfor -%}
{%- if not loop.last -%},
{%- endif -%}
{%- endfor -%}
]
- name: "Template files loop"
ansible.builtin.template:
src: "{{ curr_file.split(',')[-1] }}.yml.j2"
dest: "/tmp/{{ team_project_name }}/group_vars/{{ curr_file.split(',')[0] }}/{{ curr_file.split(',')[-1] }}.yml"
lstrip_blocks: true
mode: "0640"
loop: "{{ template_loop }}"
loop_control:
loop_var: curr_file
- name: Remove obsolete empty lines from controller_credentials.yml
ansible.builtin.replace:
path: "/tmp/{{ team_project_name }}/group_vars/{{ curr_env2 }}/controller_credentials.yml"
after: ' username:'
regexp: '(^\s*$)'
replace: ''
loop: "{{ env_list }}"
loop_control:
loop_var: curr_env2
- name: Push the updated GitLab repository and create merge request # noqa: command-instead-of-module
ansible.builtin.shell: |
git add --all
git commit -m 'initial config'
git push origin initial -o merge_request.create -o merge_request.target="{{ gitlab_default_branch }}" -o merge_request.merge_when_pipeline_succeeds
args:
chdir: "/tmp/{{ team_project_name }}"
changed_when: false
- name: Delete the tempory directory
ansible.builtin.file:
path: /tmp/{{ team_project_name }}
state: absent
- name: Protected branch block
block:
- name: Protect created branches
community.general.gitlab_protected_branch:
api_url: "{{ gitlab_protocol }}{{ gitlab_url }}"
validate_certs: "{{ gitlab_validate_certs }}"
api_username: "{{ gitlab_user_username }}"
api_password: "{{ gitlab_user_password }}"
project: "{{ gitlab_group }}/{{ team_project_name }}"
name: "{{ benv.key }}"
merge_access_levels: maintainer
push_access_level: maintainer
no_log: true
loop: "{{ aap_env | dict2items }}"
loop_control:
loop_var: benv
rescue:
- name: Print only in case of protection error
ansible.builtin.debug:
msg:
- "The branches for the repository were not protected, due to an error."
- "The error is that the account used to create the repository is not "
- "the owner of the repository."
- "Please set the protection manually...."
- name: Fail the playbook due to error.
ansible.builtin.fail:
msg: "Creation was succesfull, only the branch protection was not set, see message above"
- name: GitLab Post | Obtain Access Token
ansible.builtin.include_tasks:
file: get_gitlab_api_token.yml
- name: Check the pipeline until it has run
ansible.builtin.uri:
url: "{{ gitlab_protocol }}{{ gitlab_url }}api/v4/projects/{{ gitlab_group_safe }}%2F{{ team_project_name }}/jobs"
validate_certs: "{{ gitlab_validate_certs }}"
headers:
Authorization: "Bearer {{ token }}"
register: _jobs_list
failed_when: _jobs_list.json[0].pipeline.status == "failed"
until: (_jobs_list.json[0].pipeline.status == "success") or (_jobs_list.json[0].pipeline.status == "failed")
retries: 30
delay: 15
# Add the new organization repository to the recovery process for both environments
# you could create a loop for this
- name: Clone the Recovery DEV Branch gitlab repository
ansible.builtin.git:
repo: "https://{{ gitlab_user_username }}:{{ gitlab_user_password }}@{{ gitlab_url }}/cac_26/recover_rhaap.git"
dest: "/tmp/recover_rhaap"
version: dev
clone: true
update: true
- name: Add new EE to Recovery DEV Branch env_vars
ansible.builtin.lineinfile:
path: "/tmp/recover_rhaap/env_vars.yml"
line: " - {{ gitlab_group }}/{{ team_project_name }}"
insertafter: " - cac_26/rhaap_cac_"
- name: Push the new env_vars to Recovery DEV Branch GIT # noqa: command-instead-of-module
ansible.builtin.shell: |
git config --global user.name "{{ gitlab_user_username }}"
git config --global user.email "{{ gitlab_user_username }}@homelab"
git add --all
git commit -m 'initial config'
git push origin dev
args:
chdir: "/tmp/recover_rhaap"
changed_when: false
- name: Delete the tempory recovery DEV directory
ansible.builtin.file:
path: "/tmp/recovery_rhaap"
state: absent
- name: Clone the Recovery MAIN Branch gitlab repository
ansible.builtin.git:
repo: "https://{{ gitlab_user_username }}:{{ gitlab_user_password }}@{{ gitlab_url }}/cac_26/recover_rhaap.git"
dest: "/tmp/recover_rhaap"
version: master
clone: true
update: true
- name: Add new EE to Recovery MAIN Branch env_vars
ansible.builtin.lineinfile:
path: "/tmp/recover_rhaap/env_vars.yml"
line: " - {{ gitlab_group }}/{{ team_project_name }}"
insertafter: " - cac_26/rhaap_cac_"
- name: Push the new env_vars to MAIN Branch GIT # noqa: command-instead-of-module
ansible.builtin.shell: |
git config --global user.name "{{ gitlab_user_username }}"
git config --global user.email "{{ gitlab_user_username }}@homelab"
git add --all
git commit -m 'initial config'
git push origin master
args:
chdir: "/tmp/recover_rhaap"
changed_when: false
- name: Delete the tempory recovery MAIN directory
ansible.builtin.file:
path: "/tmp/recovery_rhaap"
state: absent