Skip to content

feat: add ansible execution environment for playbooks #806

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 24, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .ansible-lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---

exclude_paths:
- ansible/.venv/
4 changes: 4 additions & 0 deletions .github/workflows/containers.yaml
Original file line number Diff line number Diff line change
@@ -7,12 +7,14 @@ on:
branches:
- main
paths:
- "ansible/**"
- "containers/**"
- ".github/workflows/containers.yaml"
- "python/**"
pull_request:
types: [opened, synchronize, reopened, closed]
paths:
- "ansible/**"
- "containers/**"
- ".github/workflows/containers.yaml"
- "python/**"
@@ -123,6 +125,7 @@ jobs:
container:
- name: ironic-nautobot-client
- name: nova-flavors
- name: ansible

steps:
- name: setup docker buildx
@@ -182,6 +185,7 @@ jobs:
- dnsmasq
- ironic-nautobot-client
- nova-flavors
- ansible

steps:
- name: clean up PR container
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -48,6 +48,15 @@ repos:
- id: ruff
args: [--fix]
- id: ruff-format
- repo: https://github.com/ansible/ansible-lint
rev: v25.1.2
hooks:
- id: ansible-lint
entry: "sh -c 'cd ansible && python3 -m ansiblelint -v --force-color'"
additional_dependencies:
- ansible
- jmespath
files: '^ansible/.*$'
- repo: https://github.com/python-poetry/poetry
rev: '1.7.1'
hooks:
20 changes: 20 additions & 0 deletions ansible/playbooks/debug.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
# Copyright (c) 2025 Rackspace Technology, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

- name: Debug
hosts: localhost

roles:
- role: debug
30 changes: 30 additions & 0 deletions ansible/playbooks/keystone_bootstrap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# Copyright (c) 2025 Rackspace Technology, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

- name: Keystone Bootstrap
hosts: keystone
connection: local

pre_tasks:
- name: Fail if ENV variables are not set
ansible.builtin.fail:
msg: "Environment variable {{ item }} is not set. Exiting playbook."
when: lookup('env', item) == ''
loop:
- OS_USERNAME
- OS_DEFAULT_DOMAIN

roles:
- role: keystone_bootstrap
7 changes: 7 additions & 0 deletions ansible/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ansible-core==2.18.4
ansible-runner==2.4.0
openstacksdk==4.3.0
pynautobot==2.6.1
jmespath==1.0.1
# remove me after the inherited roles workaround can be dropped
python-openstackclient
7 changes: 7 additions & 0 deletions ansible/requirements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
collections:
- name: community.general
version: "==10.5.0"
- name: openstack.cloud
version: "==2.4.1"
- name: networktocode.nautobot
version: "==5.6.0"
18 changes: 18 additions & 0 deletions ansible/roles/debug/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
# Copyright (c) 2025 Rackspace Technology, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

- name: Debug
ansible.builtin.debug:
msg: debug
21 changes: 21 additions & 0 deletions ansible/roles/keystone_bootstrap/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
keystone_bootstrap_dex_url: "{{ dex_url | default('https://dex.' + lookup('ansible.builtin.env', 'DNS_ZONE', default='localnet')) }}"

keystone_bootstrap_groups:
- name: ucadmin
desc: 'Users Federated with Admin'
roles:
- member
- admin
- name: ucuser
desc: 'Regular Federated Users'
roles:
- member
- name: ucneteng
desc: 'Federated Network Engineers'
roles:
- member
- name: ucdctech
desc: 'Federated DC Technicians'
roles:
- member
27 changes: 27 additions & 0 deletions ansible/roles/keystone_bootstrap/tasks/baremetal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
# Copyright (c) 2025 Rackspace Technology, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

- name: Create 'infra' domain
openstack.cloud.identity_domain:
name: infra
description: 'System Infra'
state: present

- name: Create 'baremetal' project in 'infra' domain
openstack.cloud.project:
name: baremetal
domain: infra
description: 'Ironic Resources'
state: present
17 changes: 17 additions & 0 deletions ansible/roles/keystone_bootstrap/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---

- name: Admin needs admin role for default domain
openstack.cloud.role_assignment:
user: "{{ lookup('ansible.builtin.env', 'OS_USERNAME', default=Undefined) }}"
domain: "{{ lookup('ansible.builtin.env', 'OS_DEFAULT_DOMAIN', default=Undefined) }}"
role: admin
state: present

- name: Define baremetal
ansible.builtin.include_tasks: baremetal.yml

- name: Define SSO
ansible.builtin.include_tasks: sso.yml

- name: Define misc keystone
ansible.builtin.include_tasks: misc.yml
64 changes: 64 additions & 0 deletions ansible/roles/keystone_bootstrap/tasks/misc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
# Copyright (c) 2025 Rackspace Technology, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

- name: Create 'argoworkflow' user
openstack.cloud.identity_user:
name: argoworkflow
password: demo
domain: infra
state: present

- name: Set 'argoworkflow' role
openstack.cloud.role_assignment:
domain: infra
user: argoworkflow
project: baremetal
role: admin
state: present

- name: Create 'monitoring' user
openstack.cloud.identity_user:
name: monitoring
password: monitoring_demo
domain: infra
state: present

- name: Set 'monitoring' role
openstack.cloud.role_assignment:
domain: infra
user: monitoring
project: baremetal
role: admin
state: present

- name: Create 'flavorsync' user
openstack.cloud.identity_user:
name: flavorsync
password: abcd1234
domain: service
state: present
register: _flavor_sync_user

- name: Create 'flavorsync' role
openstack.cloud.identity_role:
name: flavorsync
state: present

- name: Set 'flavorsync' role
openstack.cloud.role_assignment:
user: "{{ _flavor_sync_user.user.id }}"
domain: default
role: flavorsync
state: present
66 changes: 66 additions & 0 deletions ansible/roles/keystone_bootstrap/tasks/sso.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
# Copyright (c) 2025 Rackspace Technology, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

- name: Create 'sso' domain
openstack.cloud.identity_domain:
name: sso
description: 'SSO to dex'
state: present
register: _domain_sso

- name: Display 'sso' configuration
ansible.builtin.debug:
var: keystone_bootstrap_dex_url

- name: Create 'sso' identity provider
openstack.cloud.federation_idp:
name: sso
domain_id: "{{ _domain_sso.domain.id }}"
description: 'Identity Provider to dex'
remote_ids:
- "{{ keystone_bootstrap_dex_url }}"

- name: Create sso mapping
openstack.cloud.federation_mapping:
name: sso_mapping
rules:
- local:
- user:
id: '{0}'
name: '{1}'
email: '{2}'
groups: '{3}'
domain:
id: "{{ _domain_sso.domain.id }}"
remote:
- type: HTTP_OIDC_SUB
- type: REMOTE_USER
- type: HTTP_OIDC_EMAIL
- type: HTTP_OIDC_GROUPS

- name: Create openid protocol
openstack.cloud.keystone_federation_protocol:
name: openid
idp: sso
mapping: sso_mapping

- name: Create federated group mappings
ansible.builtin.include_tasks: sso_member_groups.yml
loop: "{{ keystone_bootstrap_groups }}"

- name: Grant admin for groups
ansible.builtin.include_tasks: sso_role_admin.yml
loop:
- ucadmin
28 changes: 28 additions & 0 deletions ansible/roles/keystone_bootstrap/tasks/sso_member_groups.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
# Copyright (c) 2025 Rackspace Technology, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

- name: Create group
openstack.cloud.identity_group:
name: "{{ item.name }}"
domain_id: "{{ _domain_sso.domain.id }}"
description: "{{ item.desc }}"
state: present
register: _group

# role assignment module is lacking inherited and cross domain assignments
- name: Assign member access
ansible.builtin.command: openstack role add --group "{{ _group.group.id }}" --domain default --inherited member
when: dont_set_roles is not defined
changed_when: false
31 changes: 31 additions & 0 deletions ansible/roles/keystone_bootstrap/tasks/sso_role_admin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
# Copyright (c) 2025 Rackspace Technology, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
- name: Find group
openstack.cloud.identity_group_info:
name: "{{ item }}"
domain: "{{ _domain_sso.domain.id }}"

# role assignment module is lacking inherited and cross domain assignments
- name: Assign member access
ansible.builtin.command: openstack role add --group "{{ _group.group.id }}" --domain default --inherited admin
when: dont_set_roles is not defined
changed_when: false

# role assignment module is lacking inherited and cross domain assignments
- name: Assign member access
ansible.builtin.command: openstack role add --group "{{ _group.group.id }}" --domain infra --inherited admin
when: dont_set_roles is not defined
changed_when: false
Loading