Skip to content
Draft
Show file tree
Hide file tree
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
51 changes: 51 additions & 0 deletions ansible/configs/namespace/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
= Namespace Configuration

The `namespace` configuration is designed to deploy OpenShift workloads directly to existing namespaces without requiring infrastructure provisioning or bastion hosts. This is ideal for deploying applications to shared clusters or when you only have namespace-level access.

== Features

* No infrastructure provisioning required
* Direct connection to OpenShift clusters
* Support for both token and user/password authentication
* Simplified deployment for namespace-scoped workloads
* No SSH or bastion host dependencies

== Usage

1. Copy `sample_vars.yml` to create your deployment variables file
2. Configure your OpenShift connection details
3. Define the workloads to deploy in `ocp_workloads_namespaced`
4. Run the deployment

=== Example Deployment

[source,bash]
----
ansible-navigator run ansible/main.yml -e @ansible/configs/namespace/sample_vars.yml -e @/secrets/ns.yaml -e ACTION=create
----

== Required Variables

* `sandbox_openshift_api_url`: OpenShift API endpoint
* `sandbox_openshift_namespace`: Target namespace
* Authentication (choose one):
** `sandbox_openshift_api_token`: API token
** `sandbox_openshift_user` + `sandbox_openshift_password`: Username/password

== Optional Variables

* `sandbox_openshift_cluster`: Cluster name for identification
* `sandbox_openshift_apps_domain`: Apps domain for route creation
* `sandbox_openshift_credentials`: Additional credential objects

== Workloads

Define workloads in the `ocp_workloads_namespaced` list. Each workload should be a role that can deploy to OpenShift using the provided connection variables.

Example:
[source,yaml]
----
ocp_workloads_namespaced:
- ocp_workloads_namespaced_example
- my_custom_workload
----
7 changes: 7 additions & 0 deletions ansible/configs/namespace/default_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
# Namespace Config Default Variables
# This config deploys OpenShift workloads directly to a namespace without
# requiring infrastructure

# List of namespace workloads to deploy
ocp_workloads_namespaced: []
37 changes: 37 additions & 0 deletions ansible/configs/namespace/destroy_env.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
- name: Destroy Namespaced OCP Workloads
hosts: localhost
gather_facts: false
become: false
tags:
- ocp_workloads_namespaced
tasks:
- name: Destroy namespaced workloads
when:
- ocp_workloads_namespaced | default([]) | length > 0
block:
- name: Remove namespaced workload "{{ workload_loop_var }}"
ansible.builtin.include_role:
name: "{{ workload_loop_var }}"
vars:
ACTION: "destroy"
# Pass through OpenShift connection variables
sandbox_openshift_cluster: "{{ sandbox_openshift_cluster | default('') }}"
sandbox_openshift_api_url: "{{ sandbox_openshift_api_url | default('') }}"
sandbox_openshift_apps_domain: "{{ sandbox_openshift_apps_domain | default('') }}"
sandbox_openshift_namespace: "{{ sandbox_openshift_namespace | default('') }}"
sandbox_openshift_api_token: "{{ sandbox_openshift_api_token | default('') }}"
sandbox_openshift_credentials: "{{ sandbox_openshift_credentials | default([]) }}"
sandbox_openshift_user: "{{ sandbox_openshift_user | default('') }}"
sandbox_openshift_password: "{{ sandbox_openshift_password | default('') }}"
loop: "{{ ocp_workloads_namespaced }}"
loop_control:
loop_var: workload_loop_var

- name: Destroy complete
hosts: localhost
gather_facts: false
become: false
tasks:
- debug:
msg: "Namespace workloads destroyed successfully"
30 changes: 30 additions & 0 deletions ansible/configs/namespace/lifecycle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
- name: Build inventory
ansible.builtin.import_playbook: post_infra.yml

- name: Destroy workload(s)
hosts: ocp_bastions
become: false
gather_facts: false
tags:
- step005
tasks:
- name: Fail if no action defined
when: ACTION is not defined or ACTION == ''
ansible.builtin.fail:
msg: ACTION must be defined

- name: Set facts for OpenShift cluster(s)
include_tasks: set_cluster_facts.yml

- name: Run Workloads to perform {{ ACTION }}
loop: "{{ cluster_workloads }}"
loop_control:
loop_var: __workload
label: "{{ __workload.name }}"
include_tasks: run_workload_on_clusters.yml
vars:
ACTION: destroy

- name: Cleanup
ansible.builtin.import_playbook: cleanup.yml
8 changes: 8 additions & 0 deletions ansible/configs/namespace/post_infra.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Step 002 Post Infrastructure
hosts: localhost
gather_facts: false
become: false
tasks:
- debug:
msg: "Step 002 Post Infrastructure - No infrastructure setup needed for namespace config"
8 changes: 8 additions & 0 deletions ansible/configs/namespace/post_software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Step 005 Post Software
hosts: localhost
gather_facts: false
become: false
tasks:
- debug:
msg: "Step 005 Post Software - Namespace workloads deployment completed"
8 changes: 8 additions & 0 deletions ansible/configs/namespace/pre_infra.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Step 000 Pre Infrastructure
hosts: localhost
gather_facts: false
become: false
tasks:
- debug:
msg: "Step 000 Pre Infrastructure - No infrastructure needed for namespace-only deployment"
8 changes: 8 additions & 0 deletions ansible/configs/namespace/pre_software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Step 003 Pre Software
hosts: localhost
gather_facts: false
become: false
tasks:
- debug:
msg: "Step 003 Pre Software - No infrastructure software needed"
4 changes: 4 additions & 0 deletions ansible/configs/namespace/requirements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
collections:
- name: kubernetes.core
version: 5.0.0
15 changes: 15 additions & 0 deletions ansible/configs/namespace/sample_vars.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
# Sample Variables for Namespace Config
# Copy this file and customize for your deployment

# Basic environment information
cloud_provider: none
env_type: namespace
guid: test-tt

# List of workloads to deploy
ocp_workloads_namespaced:
- ocp_workloads_namespaced_example

# Output directory for deployment artifacts
output_dir: "/tmp/output_dir/{{ guid }}"
48 changes: 48 additions & 0 deletions ansible/configs/namespace/software.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
- name: Step 004 Environment specific Software
hosts: localhost
gather_facts: false
become: false
tasks:
- debug:
msg: "Software {{ ACTION | default('provision') }} started for namespace workloads"

- name: Deploy Namespaced OCP Workloads
hosts: localhost
gather_facts: false
become: false
tags:
- ocp_workloads_namespaced
tasks:
- name: Deploy namespaced workloads
when:
- ocp_workloads_namespaced | default([]) | length > 0
block:
- name: Apply namespaced workload "{{ workload_loop_var }}"
ansible.builtin.include_role:
name: "{{ workload_loop_var }}"
vars:
ACTION: "{{ ACTION | default('provision') }}"
# Pass through OpenShift connection variables
sandbox_openshift_cluster: "{{ sandbox_openshift_cluster | default('') }}"
sandbox_openshift_api_url: "{{ sandbox_openshift_api_url | default('') }}"
sandbox_openshift_apps_domain: "{{ sandbox_openshift_apps_domain | default('') }}"
sandbox_openshift_namespace: "{{ sandbox_openshift_namespace | default('') }}"
sandbox_openshift_api_token: "{{ sandbox_openshift_api_token | default('') }}"
sandbox_openshift_credentials: "{{ sandbox_openshift_credentials | default([]) }}"
sandbox_openshift_user: "{{ sandbox_openshift_user | default('') }}"
sandbox_openshift_password: "{{ sandbox_openshift_password | default('') }}"
loop: "{{ ocp_workloads_namespaced }}"
loop_control:
loop_var: workload_loop_var

- name: Software flight-check
hosts: localhost
connection: local
gather_facts: false
become: false
tags:
- post_flight_check
tasks:
- debug:
msg: "Software {{ ACTION | default('provision') }} completed successfully"
18 changes: 18 additions & 0 deletions ansible/roles/ocp_workloads_namespaced_example/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
become_override: false
silent: false

# Default values for the namespaced example workload
ocp_workloads_namespaced_example_defaults:
app_name: "hello-world"
app_image: "quay.io/redhattraining/hello-world-nginx:v1.0"
app_replicas: 1
service_port: 8080
create_route: true
route_path: "/"
resource_limits:
cpu: "100m"
memory: "128Mi"
resource_requests:
cpu: "50m"
memory: "64Mi"
104 changes: 104 additions & 0 deletions ansible/roles/ocp_workloads_namespaced_example/readme.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
= ocp_workloads_namespaced_example

This role provides an example of how to create namespaced OpenShift workloads that can be deployed without requiring infrastructure provisioning or bastion hosts.

== Overview

This role deploys a simple nginx web server to an OpenShift namespace using a mixed approach that demonstrates both `oc` commands and `kubernetes.core` modules. It demonstrates:

* **Hybrid deployment approach**: Shows both command-line and API-based methods
* **Authentication**: Using `oc login` for robust connectivity
* **Resource creation**: Mix of `kubernetes.core.k8s` modules and `oc apply` commands
* **OpenShift-specific resources**: Routes created via `oc` commands
* **Standard Kubernetes resources**: Deployments and Services via kubernetes.core modules
* **Verification**: Using both `kubernetes.core.k8s_info` and `oc get` commands

== Requirements

* Access to an OpenShift cluster
* Either an API token or username/password credentials
* Target namespace must exist and be accessible
* Ansible kubernetes.core collection installed

== Role Variables

The role uses a dictionary `ocp_workloads_namespaced_example` with the following default values:

[source,yaml]
----
ocp_workloads_namespaced_example_defaults:
app_name: "hello-world"
app_image: "quay.io/openshifttestbed/hello-openshift:latest"
app_replicas: 1
service_port: 8080
create_route: true
route_path: "/"
resource_limits:
cpu: "100m"
memory: "128Mi"
resource_requests:
cpu: "50m"
memory: "64Mi"
----

== Connection Variables

These variables are passed from the namespace config:

* `sandbox_openshift_api_url`: OpenShift API endpoint (required)
* `sandbox_openshift_namespace`: Target namespace (required)
* `sandbox_openshift_api_token`: API token (required if not using user/password)
* `sandbox_openshift_user`: Username (required if not using token)
* `sandbox_openshift_password`: Password (required if not using token)

== Usage Example

In your namespace config variables:

[source,yaml]
----
ocp_workloads_namespaced:
- ocp_workloads_namespaced_example

# Customize the workload
ocp_workloads_namespaced_example_vars:
app_name: "my-hello-app"
app_replicas: 2
create_route: true
----

== Deployed Resources

The role creates:

1. **Deployment**: Runs the application pods
2. **Service**: Provides internal cluster access
3. **Route**: (Optional) Provides external access via OpenShift router

== Authentication

The role supports two authentication methods:

1. **API Token**: Recommended for automation
2. **Username/Password**: For interactive use

== Development

This role serves as a template for creating other namespaced workloads. Key patterns demonstrated:

=== Hybrid Approach Benefits

* **oc commands**: Better for authentication, OpenShift-specific resources, and troubleshooting
* **kubernetes.core modules**: Better for structured resource definitions and Ansible integration
* **Mixed usage**: Combines the strengths of both approaches

=== Implementation Patterns

* Use `oc login` for initial authentication (more robust connectivity)
* Use `kubernetes.core.k8s` for standard Kubernetes resources (Deployments, Services)
* Use `oc apply/delete` for OpenShift-specific resources (Routes)
* Use `kubernetes.core.k8s_info` for detailed status checking
* Use `oc get` for quick verification and troubleshooting
* Implement proper error handling and retry logic for both approaches
* Support both token and username/password authentication
* Provide comprehensive status reporting showing which methods were used
30 changes: 30 additions & 0 deletions ansible/roles/ocp_workloads_namespaced_example/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
# Do not modify this file

- name: Running Pre Workload Tasks
include_tasks:
file: ./pre_workload.yml
apply:
become: "{{ become_override | bool }}"
when: ACTION == "create" or ACTION == "provision"

- name: Running Workload Tasks
include_tasks:
file: ./workload.yml
apply:
become: "{{ become_override | bool }}"
when: ACTION == "create" or ACTION == "provision"

- name: Running Post Workload Tasks
include_tasks:
file: ./post_workload.yml
apply:
become: "{{ become_override | bool }}"
when: ACTION == "create" or ACTION == "provision"

- name: Running Workload removal Tasks
include_tasks:
file: ./remove_workload.yml
apply:
become: "{{ become_override | bool }}"
when: ACTION == "destroy" or ACTION == "remove"
Loading
Loading