Nightly Kong Mesh on ECS - preview #1486
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |