Skip to content

Adding Cloud Pod release and test workflows #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5d44301
initial test
steffyP Jun 19, 2023
f130510
testing
steffyP Jun 19, 2023
6a34703
fix workflow
steffyP Jun 19, 2023
07520d8
fix pod name
steffyP Jun 19, 2023
78bf9a2
add write permission to release workflow
steffyP Jun 19, 2023
c9a71d8
improve workflow, add both pods to the release
steffyP Jun 20, 2023
3f9c782
add test_cloudpods workflow
steffyP Jun 20, 2023
4d894d2
add debug output
steffyP Jun 20, 2023
22eebbb
fixup
steffyP Jun 20, 2023
d53e87a
fixup
steffyP Jun 20, 2023
bf4b02c
fixup2
steffyP Jun 20, 2023
0dc33c9
fixup3
steffyP Jun 20, 2023
09ed099
fixup4
steffyP Jun 20, 2023
118ca8f
fixup5
steffyP Jun 20, 2023
956f0ec
fix if-else-fi
steffyP Jun 20, 2023
a05aad3
add dependencies for localstack + awscli to workflow
steffyP Jun 20, 2023
d36fe40
fix repo name
steffyP Jun 20, 2023
ca65540
remove action, retrieve pod using api
steffyP Jun 20, 2023
6317da6
fix download-url, move retrieving of pod
steffyP Jun 20, 2023
a016328
show logs on failure
steffyP Jun 20, 2023
de4da7e
wait for rds db to be available, cleanup
steffyP Jun 21, 2023
9fda55b
set fail-fast to false
steffyP Jun 21, 2023
e43cf83
test cloudpod release
steffyP Jun 21, 2023
1c804f0
fix issue with release body, use helper for running smoke test, use a…
steffyP Jun 21, 2023
808a436
fix action name
steffyP Jun 21, 2023
c8c634f
change release notes
steffyP Jun 21, 2023
e927e1c
fix description for release; add cloudpod section in README
steffyP Jun 21, 2023
ad080a8
cleanup workflows
steffyP Jun 21, 2023
e692cc8
fix cloudpod testing workflow; add troubleshooting for pod injection
steffyP Jun 21, 2023
c55f268
move checkout of dir
steffyP Jun 21, 2023
0c1f8f0
increase LS startup timeout, remove push-trigger for cloudpod-test
steffyP Jun 21, 2023
088ca53
remove mariadb pod creation + testing
steffyP Nov 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/workflows/cloudpod_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
on:
workflow_dispatch:
inputs:
release-tag:
type: string
required: true
push:
paths-ignore:
- 'README.md'
branches:
- main

permissions:
contents: write

name: Create Release
jobs:
build:
uses: ./.github/workflows/setup.yml
secrets: inherit
with:
store-cloudpod: "true"
localstack-version: ${{ inputs.release-tag || 'latest'}}
upload:
needs: build
name: Upload Release Asset
runs-on: ubuntu-latest
steps:
- name: Download Pod Artifacts
uses: actions/download-artifact@v3
with:
name: cloudpod

- name: Display structure of downloaded files
run: ls -R

- name: Prepare Release Notes
run: |
echo "This release includes the Cloud Pod of the sample created with LocalStack Version \`${{ inputs.release-tag || 'latest'}}\`." > Release.txt
echo "### MySQL" >> Release.txt
echo "The pod was created with `mysql` engine." >> Release.txt
echo "You can click the Launchpad to inject the \`mysql\` version of the pod into your running LocalStack instance:" >> Release.txt
echo "[![LocalStack Pods Launchpad](https://localstack.cloud/gh/launch-pod-badge.svg)](https://app.localstack.cloud/launchpad?url=https://github.com/$GITHUB_REPOSITORY/releases/download/${{ inputs.release-tag || 'latest'}}/release-pod-mysql.zip)" >> Release.txt

- name: Create Release
id: create_release
uses: softprops/action-gh-release@v1
with:
tag_name: "${{ inputs.release-tag || 'latest'}}"
name: "Cloud Pod for LocalStack Version '${{ inputs.release-tag || 'latest'}}'"
body_path: ./Release.txt
files: |
./release-pod-mysql.zip
18 changes: 3 additions & 15 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
LS_LOG=trace localstack start -d
# Wait 30 seconds for the LocalStack container to become ready before timing out
echo "Waiting for LocalStack startup..."
localstack wait -t 15
localstack wait -t 30
echo "Startup complete"

- name: Deploy the application
Expand All @@ -61,21 +61,9 @@ jobs:
make bootstrap
make deploy

- name: Smoke Test
- name: Run Smoke Tests
run: |
awslocal --version
awslocal lambda invoke --cli-binary-format raw-in-base64-out --function-name my-lambda-rds-query-helper --payload '{"sqlQuery": "show tables", "secretName":"/rdsinitexample/rds/creds/mysql-01"}' output
echo "show tables:"
cat output
awslocal lambda invoke --cli-binary-format raw-in-base64-out --function-name my-lambda-rds-query-helper --payload '{"sqlQuery": "select Author from Books", "secretName":"/rdsinitexample/rds/creds/mysql-01"}' output
echo "select Author from Books:"
cat output
return_status=$(cat output | jq -r .status)
if [ "SUCCESS" != ${return_status} ]; then
echo "unexpected response: ${return_status}"
cat output
exit 1
fi
./test-helper/smoke-test.sh

- name: Show Logs
if: always()
Expand Down
77 changes: 77 additions & 0 deletions .github/workflows/setup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Setup Sample with LocalStack
on:
workflow_call:
inputs:
store-cloudpod:
required: true
type: string
localstack-version:
required: true
type: string

jobs:
setup-localstack:
name: Setup infrastructure
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.9'

- name: Setup Nodejs
uses: actions/setup-node@v3
with:
node-version: 16

- name: Install dependencies
run: |
make install

- name: Start LocalStack
env:
LOCALSTACK_API_KEY: ${{ secrets.LOCALSTACK_API_KEY }}
LOCALSTACK_VOLUME_DIR: ${{ github.workspace }}/ls_test
run: |
mkdir ls_test
ls -la ls_test
docker pull localstack/localstack-pro:${{ inputs.localstack-version }}
# Start LocalStack in the background
LS_LOG=trace localstack start -d
# Wait 30 seconds for the LocalStack container to become ready before timing out
echo "Waiting for LocalStack startup..."
localstack wait -t 30
echo "Startup complete"

- name: Deploy the application
env:
AWS_ACCESS_KEY_ID: test
AWS_SECRET_ACCESS_KEY: test
AWS_DEFAULT_REGION: us-east-1
run: |
make build
make bootstrap
make deploy

# TODO should we run smoke tests before creating the pod?
- name: Run Smoke Tests
run: |
./test-helper/smoke-test.sh

- name: Save the Cloud Pod
if: ${{ inputs.store-cloudpod == 'true' }}
uses: HarshCasper/cloud-pod-save@v0.1.0
with:
name: 'release-pod-mysql.zip'
location: 'disk'

- name: Upload Pod as Artifact
if: ${{ inputs.store-cloudpod == 'true' }}
uses: actions/upload-artifact@v3
with:
name: cloudpod
path: release-pod-mysql.zip
retention-days: 1
112 changes: 112 additions & 0 deletions .github/workflows/test_cloudpods.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: Test Released Cloud Pods

on:
schedule:
# “At 00:00 on Saturday.”
- cron: "0 0 * * 6"
workflow_dispatch:

permissions:
contents: write

jobs:
get-releases:
name: Retrieve Released Cloud Pods
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- id: set-matrix
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
output=$(gh api repos/$GITHUB_REPOSITORY/releases | jq '[.[].tag_name]')
output=$(echo $output | tr '\n' ' ')
echo "matrix=$output" >> $GITHUB_OUTPUT

test-pod-release:
needs: get-releases
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
# checkout to run the smoke-test.sh
- name: Checkout
uses: actions/checkout@v3

- name: Retrieve Pod
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# TODO the download url seems to follow the pattern $GITHUB_REPOSITORY/releases/download/{TAG}/{ASSET_NAME}
# alternatively we can query the asset-id, and browser_download_url, but it seems like an overhead
# asset_id=$(gh api repos/$GITHUB_REPOSITORY/releases/tags/latest | jq -r '.assets[]' | jq --arg DB $DB -c 'select(.name=="release-pod-\( $DB ).zip") | .id)
# download_url=$(gh api repos/$GITHUB_REPOSITORY/releases/assets/$asset_id | jq -r ".browser_download_url")
download_url="https://github.com/$GITHUB_REPOSITORY/releases/download/${{ matrix.tag }}/release-pod-${{ matrix.db }}.zip"
curl -L $download_url --output release-pod.zip
ls -la

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.9'

- name: Install Dependencies
run: |
pip install localstack awscli-local

- name: Start LocalStack
env:
LOCALSTACK_API_KEY: ${{ secrets.LOCALSTACK_API_KEY }}
LOCALSTACK_VOLUME_DIR: ${{ github.workspace }}/ls_test
DEBUG: 1
POD_LOAD_CLI_TIMEOUT: 300
run: |
mkdir ls_test
ls -la ls_test
docker pull localstack/localstack-pro:${{ matrix.tag }}
# Start LocalStack in the background
localstack start -d
# Wait 30 seconds for the LocalStack container to become ready before timing out
echo "Waiting for LocalStack startup..."
localstack wait -t 30
echo "Startup complete"

- name: Inject Pod
run: |
localstack pod load file://release-pod.zip
state=$(awslocal rds describe-db-instances | jq -r ".DBInstances[0].DBInstanceStatus")
while [ "$state" = creating ]; do
sleep 1
state=$(awslocal rds describe-db-instances | jq -r ".DBInstances[0].DBInstanceStatus")
done

- name: Run Smoke Tests
run: |
./test-helper/smoke-test.sh

- name: Show Logs
if: failure()
run: |
localstack logs

- name: Send a Slack notification
if: failure() || github.event_name != 'pull_request'
uses: ravsamhq/notify-slack-action@v2
with:
status: ${{ job.status }}
token: ${{ secrets.GITHUB_TOKEN }}
notification_title: "{workflow} has {status_message}"
message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>"
footer: "Linked Repo <{repo_url}|{repo}> | <{run_url}|View Workflow run>"
notify_when: "failure"
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

- name: Prevent Workflows from getting Stale
if: always()
uses: gautamkrishnar/keepalive-workflow@v1
with:
# this message should prevent automatic triggering of workflows
# see https://docs.github.com/en/actions/managing-workflow-runs/skipping-workflow-runs
commit_message: "[skip ci] Automated commit by Keepalive Workflow to keep the repository active"
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,50 @@ The implementation can be found in `lib/resource-initializer.ts`.

More details about the original sample can be found in the AWS blog post — [Use AWS CDK to initialize Amazon RDS instances](https://aws.amazon.com/blogs/infrastructure-and-automation/use-aws-cdk-to-initialize-amazon-rds-instances/).


## Cloud Pods

[Cloud Pods](https://docs.localstack.cloud/user-guide/tools/cloud-pods/) are a mechanism that allows you to take a snapshot of the state in your current LocalStack instance, persist it to a storage backend, and easily share it with your team members.

You can convert your current AWS infrastructure state to a Cloud Pod using the `localstack` CLI.
Check out our [Getting Started guide](https://docs.localstack.cloud/user-guide/tools/cloud-pods/getting-started/) and [LocalStack Cloud Pods CLI reference](https://docs.localstack.cloud/user-guide/tools/cloud-pods/pods-cli/) to learn more about Cloud Pods and how to use them.

To inject a Cloud Pod you can use [Cloud Pods Launchpad](https://docs.localstack.cloud/user-guide/tools/cloud-pods/launchpad/) wich quickly injects Cloud Pods into your running LocalStack container.

> **NOTE**: The Cloud Pod linked here, was created with the `latest` LocalStack version, make sure you also run `latest` when injecting.
Further, LocalStack needs to be started with the flag `RDS_MYSQL_DOCKER=1`. For different flavors check the available [releases](https://github.com/localstack/amazon-rds-init-cdk/releases).

Click here [![LocalStack Pods Launchpad](https://localstack.cloud/gh/launch-pod-badge.svg)](https://app.localstack.cloud/launchpad?url=https://github.com/localstack/amazon-rds-init-cdk/releases/download/latest/release-pod-mysql.zip) to launch the Cloud Pods Launchpad and inject the Cloud Pod for this application by clicking the `Inject` button.

![Cloud Pod injection with the Cloud Pod Launchpad](images/screenshot_launchpad.png)

Alternatively, you can inject the pod by using the `localstack` CLI.
First, you need to download the pod you want to inject from the [releases](https://github.com/localstack/amazon-rds-init-cdk/releases).
Then run:

```sh
localstack pod load file://$(pwd)/release-pod-mysql.zip
```


### Troubleshooting Cloud Pod Injection

If you are on MacOS using the Docker Desktop App, and you want to inject the mysql pod, you might need to change some settings.

The error message in LocalStack is visible when you enable debugging (`DEBUG=1`):

```
Different lower_case_table_names settings for server ('2') and data dictionary ('0').
Data Dictionary initialization failed.
```

To fix this, go to the settings of the Docker Desktop App -> General, and then select `osxfs (Legacy)` for file sharing:

![Change the Docker Desktop Setting](images/screenshot_docker_desktop_setting.png)

Apply the changes, and restart LocalStack before attempting to inject the pod again.


## Contributing

We appreciate your interest in contributing to our project and are always looking for new ways to improve the developer experience. We welcome feedback, bug reports, and even feature ideas from the community.
Expand Down
Binary file added images/screenshot_docker_desktop_setting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/screenshot_launchpad.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions test-helper/smoke-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# simple smoke test: runs two queries using the lambda that should be deployed
# which connects to the database
# it fails if the lambda cannot be called, or the database is not accessible/the tables are not available

awslocal lambda invoke --cli-binary-format raw-in-base64-out --function-name my-lambda-rds-query-helper --payload '{"sqlQuery": "show tables", "secretName":"/rdsinitexample/rds/creds/mysql-01"}' output1
echo "show tables:"
cat output1

awslocal lambda invoke --cli-binary-format raw-in-base64-out --function-name my-lambda-rds-query-helper --payload '{"sqlQuery": "select Author from Books", "secretName":"/rdsinitexample/rds/creds/mysql-01"}' output2
echo "select Author from Books:"
cat output2


return_status1=$(cat output1 | jq -r .status)
if [ "SUCCESS" != ${return_status1} ]; then
echo "unexpected response for query1: ${return_status1}"
cat output1
exit 1
fi

return_status2=$(cat output2 | jq -r .status)
if [ "SUCCESS" != ${return_status2} ]; then
echo "unexpected response for query2: ${return_status2}"
cat output2
exit 1
fi