Newer
Older
openstack-caracal-ipv4 / clientdocs / ci-integration-guide.md

Omega Cloud -- CI/Automation Integration Guide (DRAFT TEMPLATE)

TEMPLATE NOTE (removed before delivery): fields written as {{THIS}} are filled in by us per client; fields marked "you fill" come from the credential files delivered to your custodians and are entered by you, on your side, into your CI system's secret store.

How to connect a CI system (Jenkins, GitLab CI, GitHub Actions, or plain scripts) to your Omega Cloud environment. Read the Handover Pack first -- sections 4 (credential handling) and 6 (boundary items) are assumed here.

1. The one rule: pipelines use the application credential

All automation authenticates as the {{TENANT_SHORT_NAME}}-svc account's application credential ({{TENANT_SHORT_NAME}}-svc-cred). Never a password. Why this pattern:

  • Scoped: it acts only inside your project, with exactly the rights of the -svc account (member + load-balancer_member). It cannot touch identity (users, roles), quotas, or anything outside your domain -- so a leaked pipeline credential is contained by design.
  • Revocable without collateral: delete the application credential and every pipeline using it stops -- but the -svc account, its password, and your other credentials are untouched. Rotations never require us.
  • No interactive dependency: it does not expire with a password change.

The corollary boundaries (platform-enforced, not policy suggestions):

  • The application credential cannot create or delete Kubernetes clusters (section 5 below).
  • It cannot create users, grant roles, or change quotas. Pipelines that try will get a permission error -- that error is correct behavior.

2. Storing the credential in your CI system

You received the credential's id and secret in the delivered file {{TENANT_SHORT_NAME}}-svc-appcred.txt. Put both into your CI system's native secret store (in Jenkins: Manage Jenkins > Credentials, as "secret text" entries or a username/password pair), then inject them into jobs as environment variables. Never:

  • commit them to a repository (including a private one),
  • bake them into a container or VM image,
  • echo them in build output (mask them in your CI configuration).

3. clouds.yaml for pipelines

The OpenStack CLI and SDKs read clouds.yaml. A working template -- values in angle brackets are yours to fill from the delivered credential file, and the secret should be injected at job runtime, not written to disk in a repository:

clouds:
  {{TENANT_SHORT_NAME}}:
    auth_type: v3applicationcredential
    auth:
      auth_url: {{AUTH_URL}}
      application_credential_id: <id from the delivered credential file>
      application_credential_secret: <injected from your CI secret store>
    region_name: {{REGION}}
    identity_api_version: 3
    cacert: <path to the delivered CA bundle {{CA_BUNDLE_FILE}}>

Then in a pipeline step:

export OS_CLOUD={{TENANT_SHORT_NAME}}
openstack token issue

A token comes back scoped to your project; that is your smoke test. Equivalent environment-variable form (no clouds.yaml file needed):

export OS_AUTH_TYPE=v3applicationcredential
export OS_AUTH_URL={{AUTH_URL}}
export OS_IDENTITY_API_VERSION=3
export OS_CACERT=<path to the delivered CA bundle>
export OS_APPLICATION_CREDENTIAL_ID=<id>
export OS_APPLICATION_CREDENTIAL_SECRET=<from your secret store>

The same values work for Terraform/OpenTofu's OpenStack provider, Ansible's openstack.cloud collection, and the OpenStack SDK -- they all understand clouds.yaml and the OS_* variables. Do not hardcode service endpoint URLs anywhere: authenticate against {{AUTH_URL}} and let the client library discover the rest from the service catalog (openstack catalog list shows what it sees).

4. Least privilege: mint narrower credentials per pipeline

Your handover credential is intentionally capable (it can do everything the -svc account can). For production-grade hygiene, use it only as the "root" automation credential and mint narrower ones per pipeline: sign in as {{TENANT_SHORT_NAME}}-svc (password, interactively -- not from CI) and create additional application credentials with an expiry date and, where useful, a reduced role list:

openstack application credential create pipeline-nightly \
  --role member --expiration 2027-01-01T00:00:00

Give each pipeline its own credential so you can revoke one without stopping the others, and so your audit trail says which pipeline did what. Deleting a credential is immediate and self-service:

openstack application credential delete pipeline-nightly

5. Kubernetes clusters and CI

The platform's cluster machinery requires a password login (-cluster account); an application credential cannot create or delete clusters. This shapes the recommended CI pattern:

  • Recommended: create long-lived clusters manually (or on a controlled schedule) as {{TENANT_SHORT_NAME}}-cluster, outside CI. Pipelines then deploy INTO the cluster using its kubeconfig, stored in your CI secret store like any other credential.
  • Not recommended: putting the -cluster password into CI so pipelines can create clusters. If your workflow genuinely needs cluster-per-run, raise it with your account contact first -- there are capacity and quota implications too.

Everything else in this guide (networks, VMs, volumes, load balancers, secrets, floating IPs) is fully pipeline-drivable with the application credential.

6. Quota and pacing expectations

  • Your quota is the hard envelope. Every create call is checked against it server-side. Pipelines must treat quota-exceeded errors as expected, actionable failures (clean up leaked resources, or request a raise via an authorized requester) -- not as retryable platform faults. openstack quota show and openstack limits show --absolute report your envelope and current consumption; a pre-flight check in long pipelines is cheap insurance.
  • Pace your polling. Waiting on a server to go ACTIVE or a load balancer to go ONLINE should poll at 10-second intervals or slower (or use the CLI --wait flags, which do this for you). Tight polling loops add load and gain nothing.
  • Serialize heavyweight creates. Load balancers and Kubernetes clusters take minutes to build; launching many concurrently mostly makes them queue. Prefer sequential creation with waits.
  • Clean up what you create. Tag or name every pipeline-created resource with the job/build id (for example ci-{{TENANT_SHORT_NAME}}-build123-web) and make teardown a step that runs on failure too. A periodic sweep job that deletes resources older than your longest pipeline is the cheapest way to keep quota headroom. Floating IPs count against quota even when detached -- release them.

7. The worked sequence your pipelines should exercise

This is the canonical order of operations for an infrastructure pipeline on this platform -- the same order the Acceptance Checklist tests. Each step lists the surface it proves. Names below use a ci- prefix; substitute your build id convention.

  1. Authenticate + discover -- openstack token issue, then openstack catalog list. Proves credential and endpoint discovery.
  2. Network build-out -- create network, subnet (a range inside your allocation that does not collide with {{TENANT_SHORT_NAME}}-subnet), router with gateway to provider-ext, attach subnet. Or reuse the handover network for simple runs. Proves networking self-service.
  3. Security group -- create a group and rules for exactly the ports the deployment needs. Proves firewall self-service.
  4. Compute -- boot a server from a shared base image on your network with your keypair; wait for ACTIVE. Proves compute + image access.
  5. Block storage -- create a volume, attach it to the server, verify it is in-use, detach. Proves the storage path end to end.
  6. Public access -- allocate a floating IP from provider-ext, attach it, verify reachability (for example SSH or your app's health port). Proves the north-south path.
  7. Load balancer -- create a load balancer on your subnet with a listener, pool, and the server as a member; wait for ACTIVE/ONLINE. Proves the load-balancing service (your accounts already hold the required role).
  8. Secrets -- store, retrieve, and delete a test secret (this is also where TLS certificates for load balancer listeners live). Proves the secrets service.
  9. Teardown in reverse order -- member/pool/listener/load balancer, floating IP (release it), server, volume, security group, router interface/router/subnet/network. Verify with the corresponding list commands that nothing is left. Proves your cleanup discipline and returns your quota.

Run the full sequence once at onboarding (that is the Acceptance Checklist) and keep a trimmed version as your pipeline's recurring smoke test.

8. When a pipeline call fails

  1. Re-run openstack token issue -- authentication failures explain most sudden breakage (revoked/expired credential, missing CA bundle in the job environment).
  2. Check quota (openstack limits show --absolute) -- the second most common cause.
  3. A permission error on identity, quota, or cluster operations is the platform working as designed (sections 1 and 5), not an outage.
  4. Anything else that looks like a platform fault: capture the exact command and the exact error text and send them to {{ACCOUNT_CONTACT}}. Verbatim errors get fast answers; paraphrased ones do not.