nmasse-itix.threescale-cicd
ansible-cicd
This project helps you to set up Continuous Delivery with the Red Hat 3scale API Management Platform (3scale AMP).
Requirements
To use this project, you need:
- A 3scale API Management Platform (either hosted or on your own servers)
- A Red Hat SSO instance if you want to use OpenID Connect for authentication
- Two APIcast gateways (one for staging and one for production), which can be hosted or managed by you
- A Swagger 2.0 file that describes the API you want to publish
Everything is done via APIs, so you don't need an SSH connection!
On the control node, you'll need the jmespath
library. If it's not there, install it using:
pip install jmespath
You'll also need a recent version of Jinja (2.8 or higher). Upgrade with:
pip install -U Jinja2
If your control node is running on RHEL7, you can run this playbook to install any missing parts.
Example: Deploying an API on 3scale SaaS with hosted APIcast gateways
To deploy a simple "Echo API" on a SaaS 3scale instance using API Keys, follow these steps:
- Create a Swagger file for your Echo API
- Build your inventory file
- Write the playbook
- Run the playbook!
First, ensure your Swagger file (api-swagger.yaml
) contains the necessary information:
swagger: '2.0'
info:
x-threescale-system-name: 'echo-api'
title: 'Echo API'
version: '1.0'
host: 'echo-api.3scale.net'
paths:
/:
get:
operationId: Echo
summary: 'Get an echo'
description: 'Get an echo from the server'
x-threescale-smoketests-operation: true
responses:
200:
description: 'An Echo from the server'
security:
- apikey: []
securityDefinitions:
apikey:
name: api-key
in: header
type: apiKey
In this Swagger file, these fields are crucial:
x-threescale-system-name
is used for the system name in configuration.title
is used as the name of the service definition.version
is important for proper versioning.host
is the DNS name of the existing API backend.operationId
is the system name for methods/metrics.summary
anddescription
are the name and description for methods/metrics.x-threescale-smoketests-operation
flags an operation as suitable for smoke tests.security
andsecurityDefinitions
define the security for the exposed API. In this case, it's using API Keys.
Next, write the inventory
file:
[all:vars]
ansible_connection=local
[threescale]
<TENANT>-admin.3scale.net
[threescale:vars]
threescale_cicd_access_token=<ACCESS_TOKEN>
Key points in the inventory file:
- The 3scale admin portal should be in a group called
threescale
. - The 3scale access token needs to be set in the
threescale_cicd_access_token
variable. - As there’s no SSH connection (only the 3scale Admin APIs are used),
ansible_connection=local
is set for the entire inventory.
Now, create the playbook (deploy-api.yaml
):
- hosts: threescale
gather_facts: no
vars:
threescale_cicd_openapi_file: 'api-swagger.yaml'
roles:
- nmasse-itix.threescale-cicd
Main elements include:
threescale_cicd_openapi_file
is the path to your Swagger file.- The
nmasse-itix.threescale-cicd
role is being used. gather_facts: no
is necessary since there's no SSH connection to the systems.
Finally, run the playbook:
ansible-galaxy install nmasse-itix.threescale-cicd
ansible-playbook -i inventory deploy-api.yaml
Inventory
The 3scale Admin Portal referenced in the playbook that includes this role will be provisioned. In our above example, it will be <TENANT>-admin.3scale.net
because the playbook specifies hosts: threescale
which has just that one host.
If you specify multiple hosts for the 3scale Admin Portal, they will all be set up with the same configuration (useful for multi-site setups).
To connect to the 3scale Admin Portal, you'll need to provide an Access Token that has read/write privileges on the Account Management API. You can set this token at the host level, group level, or globally with the threescale_cicd_access_token
variable.
At the host level, it looks like this:
[threescale]
tenant1-admin.3scale.net threescale_cicd_access_token=123...456
tenant2-admin.3scale.net threescale_cicd_access_token=789...012
At the group level, you can define it like this:
[threescale:vars]
threescale_cicd_access_token=123...456
[threescale]
tenant1-admin.3scale.net
tenant2-admin.3scale.net
You can also set it globally, for example in the playbook variables:
- hosts: threescale
vars:
threescale_cicd_access_token: 123...456
The Red Hat SSO instance (there can only be one) is defined by the threescale_cicd_sso_issuer_endpoint
variable within the threescale
group.
Its format is https://<client_id>:<client_secret>@hostname/auth/realms/<realm>
.
The client_id
and client_secret
are used by Zync to sync 3scale applications with Red Hat SSO.
Example:
threescale_cicd_sso_issuer_endpoint=https://3scale:123@sso.acme.corp/auth/realms/acme
The APIcast instances are defined using these extra variables:
threescale_cicd_apicast_sandbox_endpoint
threescale_cicd_apicast_production_endpoint
Example:
threescale_cicd_apicast_sandbox_endpoint=http://api-test.acme.corp
threescale_cicd_apicast_production_endpoint=https://api.acme.corp
OpenAPI Specification fields
This project currently supports only OpenAPI Specification v2.0 (also known as Swagger 2.0).
You can use the following extended fields in the OpenAPI Specification:
x-threescale-system-name
in theinfo
section is used to set the system name for the configuration objects in 3scale.x-threescale-smoketests-operation
flags methods suitable for smoke tests. The method must be idempotent, read-only, and have no parameters. If no methods are flagged, smoke tests will be skipped.
If you can't use the extended fields (for example, you don't want to change your API Contract), you can use the corresponding extra variables:
threescale_cicd_api_base_system_name
threescale_cicd_openapi_smoketest_operation
Here’s an example OpenAPI Specification using the extended fields:
swagger: '2.0'
info:
x-threescale-system-name: 'echo-api'
title: 'Echo API'
version: '1.0'
host: 'echo-api.3scale.net'
paths:
/:
get:
operationId: Echo
summary: 'Get an echo'
description: 'Get an echo from the server'
x-threescale-smoketests-operation: true
responses:
200:
description: 'An Echo from the server'
security:
- apikey: []
securityDefinitions:
apikey:
name: api-key
in: header
type: apiKey
Here, echo-api
is used for the system name of the 3scale service definition and a GET
request on /
is used for smoke tests.
To achieve the same without using the OpenAPI extended fields, set the extra variables:
threescale_cicd_api_base_system_name=echo-api
threescale_cicd_openapi_smoketest_operation=Echo # operationId of the "GET /" method
The standard fields of the OpenAPI Specification used include:
- In the
info
section:title
is the display name of the 3scale service definition.version
is important for proper versioning.host
is the DNS name of the API backend you want to expose.
For each method defined:
- The
operationId
is used as the system name for the corresponding methods/metrics. - The
summary
anddescription
are used as the name and description for the methods/metrics. - The
security
andsecurityDefinitions
specify the security for the exposed API.
To map the OpenAPI Specifications to the 3scale features, some restrictions apply to the security
and securityDefinitions
structures. Specifically, there should be one and only one security requirement in the security
structure, applied globally (not per method).
You can choose between two security schemes for API access:
- OAuth / OpenID Connect
- API Key
The App Key Pair scheme isn't supported in this role, as it doesn't have a corresponding definition in OpenAPI Specifications.
To secure your API with API Key, use this in your OpenAPI Specification:
securityDefinitions:
apikey:
name: api-key
in: header
type: apiKey
security:
- apikey: []
You can change the HTTP header name to send the API Key by modifying the name
field (e.g., api-key
).
To secure it with OpenID Connect, use this:
securityDefinitions:
oidc:
type: oauth2
flow: accessCode
authorizationUrl: http://dummy/placeholder
tokenUrl: http://dummy/placeholder
scopes:
openid: Get an OpenID Connect token
security:
- oidc:
- openid
You have the flexibility to choose your OpenID Connect flow:
implicit
password
application
accessCode
Role Variables
This section describes all variables used in the role. The project aims for convention over configuration, meaning it offers sensible defaults and structured naming from the start.
threescale_cicd_openapi_file
Specifies the OpenAPI Specification file to read.
- Syntax: Full path to the OpenAPI Specification on your local system (use absolute paths).
- Required: yes
- Examples:
/tmp/openapi.yaml
or{{ playbook_dir }}/git/openapi.json
threescale_cicd_openapi_file_format
Specifies the format (JSON or YAML) of the OpenAPI Specification file.
- Syntax:
JSON
orYAML
- Required: no
- Default value:
YAML
- Example:
YAML
threescale_cicd_api_system_name
Defines the system_name of the 3scale service being provisioned.
- Syntax: lower case letters, numbers, and underscores
- Required: no
- Default value: If not defined, it will be based on
threescale_cicd_api_base_system_name
, appending the API major version and prefixing it with the environment name if applicable. - Example:
dev_my_service_1
threescale_cicd_api_base_system_name
Used to compute the threescale_cicd_api_system_name
.
- Syntax: lower case letters, numbers, and underscores
- Required: no
- Default value: If not provided, it checks for the
x-threescale-system-name
ortitle
field in the OpenAPI Specification and uses a sanitized version. Default toAPI
if none found, and0
for versioning. - Example:
my_service
Note: If both threescale_cicd_api_base_system_name
and threescale_cicd_api_system_name
are set, the latter takes precedence.
threescale_cicd_wildcard_domain
Automatically defines the public URLs for APIcast.
Syntax: DNS domain suffix
Required: no
Default value: If defined, computes endpoints based on the API system name with a suffix for staging and production.
Example: If using
threescale_cicd_wildcard_domain=acme.corp threescale_cicd_api_base_system_name=my_service
Then the resulting endpoints would be:
threescale_cicd_apicast_sandbox_endpoint=https://my-service-staging.acme.corp/ threescale_cicd_apicast_production_endpoint=https://my-service.acme.corp/
threescale_cicd_api_basepath
Defines a base path for the backend API, overriding the OpenAPI Specification's basePath
.
- Syntax: URI part starting with /
- Required: no
- Default value: the
basePath
from the OpenAPI Specification. - Examples:
/api
or/context
threescale_cicd_api_backend_hostname
Defines the backend hostname, overriding the OpenAPI Specification's host
.
- Syntax: Fully Qualified Domain Name (FQDN) with optional port
- Required: no
- Default value: the
host
from the OpenAPI Specification. - Examples:
mybackend.acme.corp
ormybackend.acme.corp:8080
threescale_cicd_api_backend_scheme
Defines the scheme to connect to the backend, overriding the schemes
field from the OpenAPI Specification.
- Syntax:
http
orhttps
- Required: no
- Default value: Defaulting to the first scheme from the OpenAPI Specification,
http
if missing. - Examples:
https
threescale_cicd_private_base_url
Defines the 3scale Private Base URL.
- Syntax:
<schema>://<host>:<port>
- Required: no
- Default value: Based on the backend scheme and hostname.
- Examples:
http://mybackend.acme.corp:8080
threescale_cicd_apicast_policies_cors
Allows enabling CORS policy on the APIcast gateway if your API should support cross-origin requests.
- Syntax: boolean
yes
orno
- Required: no
- Default value:
no
- Example:
yes
to enable CORS policy on APIcast
threescale_cicd_openapi_smoketest_operation
Defines the method from OpenAPI Specification to use for smoke tests.
- Syntax: the
operationId
from the OpenAPI Specification method. - Required: no
- Default value: If not set and no smoke test method flagged, smoke tests will be skipped.
- Example:
GetName
threescale_cicd_api_environment_name
Prefixes all services with an environment name to avoid name collisions when deploying the same API multiple times.
- Syntax: lowercase, alphanumeric, and underscore
- Required: no
- Default value: none (no prefixing).
- Examples:
dev
,test
, orprod
threescale_cicd_validate_openapi
Validates the OpenAPI Specification file using the official schema with the go-swagger tool.
You can pre-install this tool or point to its location with the threescale_cicd_goswagger_command
variable.
If the tool is missing, it can be downloaded automatically.
- Syntax: boolean (
yes
,no
,true
,false
) - Required: no
- Default value:
yes
- Examples:
threescale_cicd_validate_openapi=no
threescale_cicd_goswagger_command=/usr/local/bin/swagger
threescale_cicd_local_bin_path=/tmp
threescale_cicd_oicd_flows
Overrides or updates supported OAuth flows for this API.
- Syntax: array of strings (
[ 'application', 'accessCode' ]
) - Required: no
- Default value: defaults to
flow
from thesecurityScheme
in your OpenAPI Specification. - Examples:
threescale_cicd_oicd_flows="{{ [ 'application', 'accessCode' ] }}"
(overrides the flow list)threescale_cicd_oicd_flows="{{ [ 'application', threescale_cicd_api_security_scheme.flow ] }}"
(adds a flow)
threescale_cicd_create_default_application
Allows creating a default test application with the default application plan.
- Syntax: boolean (
yes
,no
,true
,false
) - Required: no
- Default value:
no
- Example: Set to
yes
to create a default application
Miscellaneous variables
Other variables are listed in defaults/main.yml, which provides sensible defaults. Check them out.
Dependencies
This project has no dependencies on other roles, but it requires:
- Ansible (at least version 2.4)
- JMESPath
- Jinja (version 2.8 or higher)
- 3scale API Management 2.3
Integration with other technologies
Support for major technologies is found in the support folder. This includes Jenkins, Kubernetes, Docker, OpenShift, and a pre-built docker image.
License
MIT
Author Information
- Nicolas Massé, Red Hat
- Laurent Broudoux, Red Hat
- Daria Mayorova, Red Hat
Enables Continuous Deployment with 3scale API Management Platform
ansible-galaxy install nmasse-itix.threescale-cicd