I started off with a git repo containing a simple API swagger file and product definition using $ref to point to the API swagger. From there the aim was to create a GitHub action that can publish this API into my v10 API Connect stack whenever I push changes to the API definition or add additional APIs to my product.
Firstly I went to the Actions tab on my GitHub repo and selected to create a new workflow (from scratch rather than from an existing template) - this gave me the framework for the yaml with the first step to check out the code from my repo populated.
I've also set up
secrets on my repo to contain the API key used to authenticate to IAM, and the hostnames for the manager and api host for my stack - which I reference in the env section of my workflow steps using ${{ secrets.secret-name }} to ensure they are kept out of the output.
In order to use the API Connect toolkit from within the workflow I need to download the toolkit for linux from my `/client-downloads/toolkit-linux.tgz`on my API Manager host, extract it and make it executable. The benefit of puling this from the manager is that it will ensure the version matches.
- name: Get APIC Toolkit
env:
MANAGER_HOST: manager.${{ secrets.host_suffix}}
run: |
curl -LO https://${MANAGER_HOST}/client-downloads/toolkit-linux.tgz
tar -vzxf toolkit-linux.tgz
chmod a+x apic-slim
As in my case I'm making use of API Connect Reserved instance, I then need to retrieve a token from IBM Cloud IAM to use with the API Connect toolkit (based on my article on
authentication for CI/CD in v10 Reserved). Otherwise this step would be replaced with a call to `./apic-slim login` to generate the appropriate token flow.
- name: Get IAM token
env:
API_KEY: ${{ secrets.api_key }}
API_HOST: api.${{ secrets.host_suffix}}
run: |
mkdir ~/.apiconnect/
touch ~/.apiconnect/token
ACCESS_TOKEN=$(curl -s "https://iam.cloud.ibm.com/identity/token" -H 'Content-Type: application/x-www-form-urlencoded' -H 'Accept: application/json' --data "grant_type=urn:ibm:params:oauth:grant-type:apikey&apikey=$API_KEY" | jq .access_token -r)
echo "${API_HOST}/api: |
refresh_token: \"\"
access_token: ${ACCESS_TOKEN}" > ~/.apiconnect/token
Once the token is obtained and placed in the .apiconnect/token file - I can then start to use the toolkit - for a simple test,
get the list of the orgs I have access to:
For the first call in the workflow you will need to include the --accept-license and --live-help options in order for it to run in a headless scenario.
- name: List orgs with apic CLI
env:
API_HOST: api.${{ secrets.host_suffix}}
run: |
./apic-slim orgs --accept-license --live-help --my --server ${API_HOST}
Now I have the API Connect toolkit working, I can actually do the
products:publish - this time I've used environment variables to specify the org name and catalog for ease of maintenance. At the moment as my API is a basic health check which doesn't yet use authentication, I don't need to worry about migrating subscriptions with the `--migrate_subscriptions` option. If you do have subscriptions however, this would be key to ensure they are moved to the updated product.
- name: Publish product with apic CLI
env:
API_HOST: api.${{ secrets.host_suffix}}
ORG_NAME: 'test-porg'
CATALOG_NAME: 'automation'
run: |
./apic-slim products:publish --server ${API_HOST} --org ${ORG_NAME} --catalog ${CATALOG_NAME} product.yaml
This is still currently a very basic development flow and can be easily extended to support many other operations now that the CLI is available to use within the workflow. The next things I'll be exploring with this will probably be deploying to different catalogs depending on the branch and making this into a reusable action.
You can see my
full workflow in my repo.
#APIConnect#cicd#GitHub#whatsnew