nmasse-itix / threescale-cicd

An Ansible module that enables Continuous Delivery with Red Hat 3scale API Management Platform (3scale AMP)
https://galaxy.ansible.com/nmasse-itix/threescale-cicd/
MIT License
16 stars 13 forks source link
3scale ansible ansible-galaxy

ansible-cicd

Build Status MIT licensed Galaxy Role

Enables Continuous Delivery with Red Hat 3scale API Management Platform (3scale AMP).

Requirements

This role requires:

All the components are driven through APIs, so no SSH connection is required!

On the control node, the jmespath library is required. If it is not already there, you can install it with:

pip install jmespath

A recent version of Jinja (2.8) is also required. You can upgrade your Jinja version with:

pip install -U Jinja2

If your control node runs on RHEL7, you can run this playbook to install the missing dependencies.

Example: Deploy an API on 3scale SaaS with hosted APIcast gateways

If you want to deploy the classic "Echo API" on a SaaS 3scale instance using API Keys, you can do it in three steps:

  1. Craft a Swagger file for your Echo API
  2. Build your inventory file
  3. Write the playbook
  4. Run the playbook!

First, make sure your swagger file (api-swagger.yaml) has the required 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, the following fields are used:

Then, write the inventory file:

[all:vars]
ansible_connection=local

[threescale]
<TENANT>-admin.3scale.net

[threescale:vars]
threescale_cicd_access_token=<ACCESS_TOKEN>

The important bits of the inventory file are:

You can now write the playbook (deploy-api.yaml):

- hosts: threescale
  gather_facts: no
  vars:
    threescale_cicd_openapi_file: 'api-swagger.yaml'
  roles:
  - nmasse-itix.threescale-cicd

The main parts are:

Finally, you can run the playbook:

ansible-galaxy install nmasse-itix.threescale-cicd
ansible-playbook -i inventory deploy-api.yaml

Inventory

The 3scale Admin Portal that will be provisionned is the one that is referenced in the playbook that includes this role. For instance, in the previous example, the provisioned 3scale Admin Portal will be <TENANT>-admin.3scale.net because the main playbook specifies hosts: threescale and the threescale group contains only one host: <TENANT>-admin.3scale.net.

If you specifies multiple hosts for the 3scale Admin Portal, they all will be provisionned with the exact same configuration (useful for multi-site deployments).

To connect to the 3scale Admin Portal, you will have to provide an Access Token having read/write privileges on the Account Management API. You can provide this token at the host level, group level or globally with the threescale_cicd_access_token variable.

At the host level, it is defined as such:

[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 as such:

[threescale:vars]
threescale_cicd_access_token=123...456

[threescale]
tenant1-admin.3scale.net
tenant2-admin.3scale.net

And you can also define it globally, for instance as playbook vars:

- hosts: threescale
  vars:
    threescale_cicd_access_token: 123...456

The Red Hat SSO instance (currently there can only be one), is defined by the threescale_cicd_sso_issuer_endpoint variable of the threescale group.

Its syntax is https://<client_id>:<client_secret>@hostname/auth/realms/<realm>. The client_id/client_secret are used by Zync to synchronize the 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 from the following extra variables:

Example:

threescale_cicd_apicast_sandbox_endpoint=http://api-test.acme.corp
threescale_cicd_apicast_production_endpoint=https://api.acme.corp

OpenAPI Specification fields

This role currently supports only OpenAPI Specifications v2.0 (aka. Swagger 2.0).

The following extended fields of the OpenAPI Specifications can be used:

If the extended fields cannot be used (if for instance you do not want to alter your API Contract), you can use the corresponding extra variable:

Here is an example of an OpenAPI Specification using those 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

Namely, echo-api would be used as a basis to construct the system_name of the 3scale service definition and a GET on / would be used as smoketests.

To achieve the same effect without the OpenAPI extended fields, you would have to pass the following extra variables:

threescale_cicd_api_base_system_name=echo-api
threescale_cicd_openapi_smoketest_operation=Echo # The operationId of the "GET /" method

The following standard fields of the OpenAPI Specifications are used.

In the info section:

For each defined method:

To have a one-to-one mapping between the OpenAPI Specifications and the 3scale features, some restrictions are applied on the security/securityDefinitions structures. Namely, there must be one and exactly one security requirement in the security structure. The security requirement needs to be applied globally (not on a per method basis).

The security definitions also have restrictions: you can choose between only two security schemes:

The App Key Pair scheme proposed by 3scale has no corresponding definition in the OpenAPI Specifications and is currently not supported by this role.

So to be more concrete, to secure your API with API Key, use this excerpt in your OpenAPI Specification file:

securityDefinitions:
  apikey:
    name: api-key
    in: header
    type: apiKey
security:
- apikey: []

You can of course, choose the HTTP header name that will be used to send the API Key by changing the name field (in this example: api-key).

And to secure it with OpenID Connect use this excerpt in your OpenAPI Specification file:

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 can of course use the OpenID Connect flow of your choice:

Role Variables

This section presents extensively all the variables used by this role. As a foreword, this role adopt a convention-over-configuration scheme. This means that sensible defaults and opinionated naming schemes are provided out-of-the-box.

threescale_cicd_openapi_file

Specifies the OpenAPI Specification file to read.

threescale_cicd_openapi_file_format

Specifies the format (JSON or YAML) of the OpenAPI Specification file to read.

threescale_cicd_api_system_name

Defines the system_name of the 3scale Service that will be provisioned.

threescale_cicd_api_base_system_name

Is used as a basis to compute the threescale_cicd_api_system_name.

Note: If both threescale_cicd_api_base_system_name and threescale_cicd_api_system_name are set, the later has precedence.

threescale_cicd_wildcard_domain

Automatically defines the APIcast public URLs based on a scheme.

threescale_cicd_api_basepath

Defines a basePath on which is deployed the backend API, overriding the basePath field of the OpenAPI Specification. The resulting value is used to define the mapping rules of the 3scale API Gateway, prepending this base path to paths of different methods/operations.

threescale_cicd_api_backend_hostname

Defines the backend hostname, overriding the host field of the OpenAPI Specification. The resulting value is used to define the threescale_cicd_private_base_url variable if missing.

threescale_cicd_api_backend_scheme

Defines the scheme to use to connect to the backend, overriding the schemes field of the OpenAPI Specification. The resulting value is used to define the threescale_cicd_private_base_url variable if missing.

threescale_cicd_private_base_url

Defines the 3scale Private Base URL.

threescale_cicd_apicast_policies_cors

Allows to enable the CORS policy onto APICast gateway. In case your API should support cross-origin and browser based invocations and you do not have included the OPTIONS verb on correct path into your OpenAPI Specification file...

threescale_cicd_openapi_smoketest_operation

Defines the OpenAPI Specification method to use for smoke tests.

threescale_cicd_api_environment_name

Prefixes all services with an environment name to prevent any name collision when deploying the same API multiple times on the same 3scale instance.

threescale_cicd_validate_openapi

Validates the OpenAPI Specification file against the official schema. To do this, the go-swagger tool is used.

You can pre-install this tool somewhere in your PATH. Alternatively, you can also point the complete path to the swagger command with the threescale_cicd_goswagger_command extra variable.

If the tool is missing, it will be automatically downloaded from GitHub and installed in {{ threescale_cicd_local_bin_path }}.

threescale_cicd_oicd_flows

Override or update the list of supported OAuth flows for this API.

threescale_cicd_create_default_application

Allows to create a test application with the default application plan, whether smoke tests are enabled or not.

Miscellaneous variables

Miscellaneous variables defined in defaults/main.yml provide sensible defaults. Have a look at them.

Dependencies

This role has no dependencies on other roles, but it has dependencies on:

Integration with other technologies

Support for major technologies is available in the support folder. There is support for Jenkins, Kubernetes, Docker, OpenShift, including a pre-built docker image.

License

MIT

Author Information