Skip to content

Nightly Kong Mesh on ECS - preview #1484

Nightly Kong Mesh on ECS - preview

Nightly Kong Mesh on ECS - preview #1484

Workflow file for this run

name: "Nightly Kong Mesh on ECS"
run-name: "Nightly Kong Mesh on ECS - ${{ inputs.version || 'preview' }}"
concurrency:
group: ${{github.workflow}}
on:
workflow_dispatch:
inputs:
version:
description: Kong Mesh version to build (same format as installer.sh). Otherwise latest preview is used.
type: string
skip-cleanup:
description: Skip resource cleanup
type: boolean
required: false
schedule:
- cron: "25 4 * * *"
push:
branches:
- main
env:
stack-prefix: ecs-ci
unique-id: ${{ github.run_number }}_${{ github.run_attempt}}
permissions:
id-token: write
contents: read
# In the AWS account, GitHub is registered as an OIDC provider.
# There is also an IAM role that trusts tokens issued by this provider to this
# main branch in this repository. The role has permissions necessary to create
# and delete the stacks in this repo (see /policy.json).
#
# When the GitHub workflow runs, it is issued such an OIDC token by the GitHub OIDC
# provider and uses the `configure-aws-credentials` action to obtain short-lived
# credentials and then assume the aforementioned IAM role.
jobs:
test:
timeout-minutes: 30
name: "Test Kong Mesh on ECS"
runs-on: ubuntu-latest
defaults:
run:
shell: /usr/bin/bash -Eeuo pipefail {0}
outputs:
# Note that these are the _names_ and not the ARNs since it appears GH
# refuses to export a value if it contains a secret, in this case the AWS
# account id.
license-secret: ${{ steps.cp.outputs.license-secret }}
tls-key-secret: ${{ steps.cp.outputs.tls-key-secret }}
tls-cert-secret: ${{ steps.cp.outputs.tls-cert-secret }}
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a #v4.3.1
with:
role-to-assume: arn:aws:iam::${{ secrets.NIGHTLY_AWS_ACCOUNT_ID }}:role/ecs-ci
aws-region: us-east-2
- name: Generate GitHub app token
id: github-app-token
uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
with:
app_id: ${{ vars.KONG_MESH_APP_ID }}
private_key: ${{ secrets.KONG_MESH_APP_PRIVATE_KEY }}
- name: Get version
id: version
env:
GH_TOKEN: ${{ steps.github-app-token.outputs.token }}
run: |
version="${{ inputs.version }}"
if [[ -z "${version}" ]] || [[ "${version}" == "preview" ]]; then
version=$(curl --silent -L https://docs.konghq.com/mesh/installer.sh | VERSION=preview sh -s - --print-version | tail -n1)
fi
echo "version=${version}" >> $GITHUB_OUTPUT
- name: Install kumactl
run: |
curl -L https://docs.konghq.com/mesh/installer.sh | VERSION="${{ steps.version.outputs.version }}" sh -
cp kong-mesh-*/bin/kumactl /usr/local/bin/kumactl
- name: Provision VPC
run: |
aws cloudformation deploy \
--capabilities CAPABILITY_IAM \
--stack-name ${{ env.stack-prefix}}-vpc \
--template-file deploy/vpc.yaml
- name: Provision control plane
id: cp
env:
license: ${{ secrets.KONG_MESH_LICENSE_JSON }}
run: |
LICENSE_SECRET=$(
aws secretsmanager create-secret \
--name ${{ env.stack-prefix }}/KongMeshLicense/${{ env.unique-id }} \
--description "Secret containing Kong Mesh license" \
--secret-string "${license}"
)
CP_ADDR=$(
aws cloudformation describe-stacks --stack-name ${{ env.stack-prefix}}-vpc \
| jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "ExternalCPAddress") | .OutputValue'
)
kumactl generate tls-certificate --type=server --hostname ${CP_ADDR} --hostname controlplane.kongmesh
TLS_KEY=$(
aws secretsmanager create-secret \
--name ${{ env.stack-prefix }}/CPTLSKey/${{ env.unique-id }} \
--description "Secret containing TLS private key for serving control plane traffic" \
--secret-string file://key.pem
)
TLS_CERT=$(
aws secretsmanager create-secret \
--name ${{ env.stack-prefix }}/CPTLSCert/${{ env.unique-id }} \
--description "Secret containing TLS certificate for serving control plane traffic" \
--secret-string file://cert.pem
)
aws cloudformation deploy \
--capabilities CAPABILITY_IAM \
--stack-name ${{ env.stack-prefix}}-cp \
--parameter-overrides VPCStackName=${{ env.stack-prefix }}-vpc \
Image="docker.io/kong/kuma-cp:${{ steps.version.outputs.version }}" \
LicenseSecret=$(jq -r .ARN <<< $LICENSE_SECRET) \
ServerKeySecret=$(jq -r .ARN <<< $TLS_KEY) \
ServerCertSecret=$(jq -r .ARN <<< $TLS_CERT) \
--template-file deploy/controlplane.yaml
echo "license-secret=$(jq -r .Name <<< $LICENSE_SECRET)" >> $GITHUB_OUTPUT
echo "cp-addr=${CP_ADDR}" >> $GITHUB_OUTPUT
echo "tls-key-secret=$(jq -r .Name <<< $TLS_KEY)" >> $GITHUB_OUTPUT
echo "tls-cert-secret=$(jq -r .Name <<< $TLS_CERT)" >> $GITHUB_OUTPUT
- name: Setup kumactl
run: |
TOKEN_SECRET_ARN=$(
aws cloudformation describe-stacks --stack-name ${{ env.stack-prefix }}-cp \
| jq -r '.Stacks[0].Outputs[] | select(.OutputKey == "APITokenSecret") | .OutputValue'
)
# The token may not have been put in the secret by the CP task yet
wait_num=15
while aws secretsmanager list-secret-version-ids --secret-id ${TOKEN_SECRET_ARN} | jq -e '.Versions | length == 0' >/dev/null; do
if (( wait_num-- <= 0 )); then
>&2 echo "Timed out waiting for control plane admin token"
exit 1
fi
echo "Waiting for control plane to save admin token..."
sleep 10s
done
TOKEN=$(
aws secretsmanager get-secret-value --secret-id ${TOKEN_SECRET_ARN} \
| jq -r .SecretString
)
echo "Setting up kumactl with ECS control plane"
# While testing it seems to be possible for a connection to succeed
# with netcat then fail with kumactl, so just make sure enough have
# worked before running `kumactl`
echo "Ensuring open TCP connection to control plane listener..."
for i in {1..5}; do
netcat -w 180 -z ${{ steps.cp.outputs.cp-addr }} 5682 || true
done
kumactl config control-planes add \
--name=ecs \
--address=https://${{ steps.cp.outputs.cp-addr }}:5682 \
--auth-type=tokens \
--auth-conf token=${TOKEN} \
--ca-cert-file cert.pem
- name: Provision counter-demo
run: |
aws cloudformation deploy \
--capabilities CAPABILITY_IAM \
--stack-name ${{ env.stack-prefix }}-redis \
--parameter-overrides \
SidecarImage="docker.io/kong/kuma-dp:${{ steps.version.outputs.version }}" \
VPCStackName=${{ env.stack-prefix }}-vpc \
CPStackName=${{ env.stack-prefix }}-cp \
--template-file deploy/counter-demo/redis.yaml
aws cloudformation deploy \
--capabilities CAPABILITY_IAM \
--stack-name ${{ env.stack-prefix }}-demo-app \
--parameter-overrides \
SidecarImage="docker.io/kong/kuma-dp:${{ steps.version.outputs.version }}" \
VPCStackName=${{ env.stack-prefix }}-vpc \
CPStackName=${{ env.stack-prefix }}-cp \
--template-file deploy/counter-demo/demo-app.yaml
- name: Test that Dataplanes exist
run: |
test $(kumactl get dataplanes -o json | jq '.items | length') -eq 2
- name: Test counter-demo
run: |
sudo apt-get install httpie
echo "Ensuring open TCP connection to demo app listener..."
for i in {1..5}; do
netcat -w 180 -z ${{ steps.cp.outputs.cp-addr }} 80 || true
done
COUNTER=$(http --check-status GET http://${{ steps.cp.outputs.cp-addr }}/counter | jq -r .counter)
NEXT_COUNTER=$(http --check-status POST http://${{ steps.cp.outputs.cp-addr }}/increment | jq -r .counter)
test $((NEXT_COUNTER - COUNTER)) -eq 1
teardown:
timeout-minutes: 30
needs: test
name: "Cleanup"
if: 'always() && !inputs.skip-cleanup'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a #v4.3.1
with:
role-to-assume: arn:aws:iam::${{ secrets.NIGHTLY_AWS_ACCOUNT_ID }}:role/ecs-ci
aws-region: us-east-2
- name: Deprovision counter-demo & controller
run: |
aws cloudformation delete-stack \
--stack-name ${{ env.stack-prefix}}-demo-app
aws cloudformation delete-stack \
--stack-name ${{ env.stack-prefix}}-redis
aws cloudformation wait stack-delete-complete \
--stack-name ${{ env.stack-prefix}}-demo-app
aws cloudformation wait stack-delete-complete \
--stack-name ${{ env.stack-prefix}}-redis
- name: Deprovision control plane
run: |
aws cloudformation delete-stack \
--stack-name ${{ env.stack-prefix}}-cp
aws cloudformation wait stack-delete-complete \
--stack-name ${{ env.stack-prefix}}-cp
aws secretsmanager delete-secret --secret-id ${{ needs.test.outputs.tls-key-secret }}
aws secretsmanager delete-secret --secret-id ${{ needs.test.outputs.tls-cert-secret }}
aws secretsmanager delete-secret --secret-id ${{ needs.test.outputs.license-secret }}
- name: Deprovision VPC
run: |
aws cloudformation delete-stack \
--stack-name ${{ env.stack-prefix}}-vpc
aws cloudformation wait stack-delete-complete \
--stack-name ${{ env.stack-prefix}}-vpc