Skip to content

Commit

Permalink
Merge branch 'main' into readmemodule
Browse files Browse the repository at this point in the history
  • Loading branch information
phbnf authored Dec 5, 2024
2 parents fb43234 + 3caa332 commit a1eb16a
Show file tree
Hide file tree
Showing 8 changed files with 515 additions and 19 deletions.
154 changes: 154 additions & 0 deletions .github/workflows/aws_integration_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
name: AWS Conformance Test

on:
push:
branches:
- main

# This prevents two workflows from running at the same time.
# This workflows calls terragrunt, which does not allow concurrent runs.
concurrency:
group: aws-conformance
cancel-in-progress: false

permissions:
contents: read

env:
TF_VERSION: "1.10.0"
TG_VERSION: "0.67.0"
TG_DIR: "deployment/live/aws/conformance/ci/"
TESSERA_PREFIX_NAME: trillian-tessera
ECR_REGISTRY: 864981736166.dkr.ecr.us-east-1.amazonaws.com
ECR_REPOSITORY_CONFORMANCE: trillian-tessera/conformance:latest
ECR_REPOSITORY_HAMMER: trillian-tessera/hammer:latest
AWS_REGION: us-east-1

jobs:
aws-integration:
runs-on: ubuntu-latest

steps:
## Authenticate to AWS with the credentials stored in Github Secrets.
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
# TODO(phboneff): use a better form of authentication
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}

- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

## Authenticate with ECR to push the conformance and hammer images.
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2

## Build the conformance image and push it to ECR. This will be used
## later on by Terragrunt.
- name: Build, tag, and push Conformance image to Amazon ECR
id: build-publish-conformance
shell: bash
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ECR_REPOSITORY_CONFORMANCE }}
run: |
docker build -f ./cmd/conformance/aws/Dockerfile . -t "$ECR_REGISTRY/$ECR_REPOSITORY"
docker push "$ECR_REGISTRY/$ECR_REPOSITORY"
echo "Pushed image to $ECR_REGISTRY/$ECR_REPOSITORY"
## Build the hammer image and push it to ECR. This will be used
## later on by Terragrunt.
- name: Build, tag, and push Hammer image to Amazon ECR
id: build-publish-hammer
shell: bash
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ env.ECR_REPOSITORY_HAMMER }}
run: |
docker build -f ./internal/hammer/Dockerfile . -t "$ECR_REGISTRY/$ECR_REPOSITORY"
docker push "$ECR_REGISTRY/$ECR_REPOSITORY"
echo "Pushed image to $ECR_REGISTRY/$ECR_REPOSITORY"
## Destroy any pre-existing deployment/live/aws/conformance/ci env.
## This might happen if a previous integration test workflow has failed.
- name: Terragrunt destroy pre conformance test
id: terragrunt-destroy-pre
uses: gruntwork-io/terragrunt-action@v2
with:
tf_version: ${{ env.TF_VERSION }}
tg_version: ${{ env.TG_VERSION }}
tg_dir: ${{ env.TG_DIR }}
tg_command: "destroy"
env:
TESSERA_SIGNER: unused
TESSERA_VERIFIER: unused

## Generate a new keys for the log to use, and export them to environment
## variables for Terragrunt to use.
- name: Generate Tessera keys
id: generate-keys
shell: bash
run: |
go run github.com/transparency-dev/serverless-log/cmd/generate_keys@80334bc9dc573e8f6c5b3694efad6358da50abd4 \
--key_name=tessera/test/conformance \
--out_priv=${{ runner.temp }}/key.sec \
--out_pub=${{ runner.temp }}/key.pub
cat ${{ runner.temp }}/key.pub
echo "TESSERA_SIGNER=$(cat ${{ runner.temp }}/key.sec)" >> "$GITHUB_ENV"
echo "TESSERA_VERIFIER=$(cat ${{ runner.temp }}/key.pub)" >> "$GITHUB_ENV"
## Apply the deployment/live/aws/conformance/ci terragrunt config.
## This will bring up the conformance infrastructure which consists of:
## - the storage module
## - a private S3 <--> ECS network link for the hammer to read the log
## - an ECS cluster to run Fargate tasks
## - a conformance service, with multiple conformance binary instances
## - a hammer task definition (but no execution)
# TODO(phboneff): AuroraDB takes a long time to be brought up and down
# consider keeping it around between tests / using Aurora Serveless
- name: Terragrunt apply
id: terragrunt-apply
uses: gruntwork-io/terragrunt-action@v2
with:
tf_version: ${{ env.TF_VERSION }}
tg_version: ${{ env.TG_VERSION }}
tg_dir: ${{ env.TG_DIR }}
tg_command: "apply"
env:
INPUT_POST_EXEC_1: |
echo "ECS_CLUSTER=$(terragrunt output -raw ecs_cluster)" >> "$GITHUB_ENV"
INPUT_POST_EXEC_2: |
echo "VPC_SUBNETS=$(terragrunt output -json vpc_subnets)" >> "$GITHUB_ENV"
## Now we can run the hammer using the task definition, against the
## conformance service. This step returns the hammer task's exit code.
- name: Run Hammer
id: hammer
shell: bash
run: |
cat ${{ runner.temp }}/key.pub
echo "Will launch a hammer ECS task."
HAMMER_ARN=$(aws ecs run-task \
--cluster="$ECS_CLUSTER" \
--task-definition=hammer \
--count=1 \
--launch-type=FARGATE \
--network-configuration='{"awsvpcConfiguration": {"assignPublicIp":"ENABLED","subnets": '$VPC_SUBNETS'}}' \
--query 'tasks[0].taskArn')
echo "Hammer task running, ARN: $HAMMER_ARN."
echo "Waiting for task to stop..."
aws ecs wait tasks-stopped --cluster="$ECS_CLUSTER" --tasks=[$HAMMER_ARN]
echo "The task has stopped. Fetching exit code and returning this action with it."
exit $(aws ecs describe-tasks --cluster="$ECS_CLUSTER" --tasks=[$HAMMER_ARN] --query 'tasks[0].containers[0].exitCode')
- name: Terragrunt destroy post conformance test
id: terragrunt-destroy-post
uses: gruntwork-io/terragrunt-action@v2
with:
tf_version: ${{ env.TF_VERSION }}
tg_version: ${{ env.TG_VERSION }}
tg_dir: ${{ env.TG_DIR }}
tg_command: "destroy"
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,10 @@ Take a look at the example personalities in the `/cmd/` directory:
- This example runs an HTTP web server that takes arbitrary data and adds it to a file-based log.
- [mysql](./cmd/conformance/mysql/): example of operating a log that uses MySQL
- This example is easiest deployed via `docker compose`, which allows for easy setup and teardown.
- [gcp](./cmd/conformance/gcp/): example of operating a log running in GCP
- This example can be deployed via terraform (see the [deployment](./deployment/) directory).
- [gcp](./cmd/conformance/gcp/): example of operating a log running in GCP.
- This example can be deployed via terraform, see the [deployment instructions](./deployment/live/gcp/conformance#manual-deployment).
- [aws](./cmd/conformance/aws/): example of operating a log running on AWS.
- This example can be deployed via terraform, see the [deployment instructions](./deployment/live/aws/codelab#aws-codelab-deployment).
- [posix-oneshot](./cmd/examples/posix-oneshot/): example of a command line tool to add entries to a log stored on the local filesystem
- This example is not a long-lived process; running the command integrates entries into the log which lives only as files.

Expand Down
9 changes: 5 additions & 4 deletions cmd/conformance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Implementations are provided that use:
- [A local POSIX-compliant filesystem](./posix/)
- [MySQL](./mysql/)
- [GCP](./gcp/)
- [AWS](deployment/live/aws/codelab/)
- [AWS](./aws/)

Each of these personalities exposes an endpoint that accepts `POST` requests at a `/add` URL.
The contents of any request body will be appended to the log, and the decimal index assigned to this newly _sequenced_ entry will be returned.
Expand All @@ -21,7 +21,7 @@ First, you need to bring up personality (a server built with Tessera which manag
- [A local POSIX-compliant filesystem](./posix#bring-up-a-log)
- [MySQL](./mysql#bring-up-a-log)
- [GCP](./gcp)
- [AWS](./aws)
- [AWS](/deployment/live/aws/codelab#aws-codelab-deployment)

Choose one of the implementations above and deploy it.
In the shell you are going to run this codelab in, define the following environment variables (check the logging output from the implementation you deployed, as these may have been output):
Expand All @@ -38,10 +38,11 @@ curl -d 'two!' -H "Content-Type: application/data" -X POST ${WRITE_URL}add &
curl -d 'three!' -H "Content-Type: application/data" -X POST ${WRITE_URL}add &
wait

# Check that the checkpoint is of the correct size
# Check that the checkpoint is of the correct size (i.e. 3).
# If the checkpoint size is zero, this is expected. It may take a second to integrate the entries and publish the checkpoint.
curl -s ${READ_URL}checkpoint

# Look at the leaves. Piping into xxd to reveal the leaf sizes.
# Look at the leaves after confirming the checkpoint size. Piping into xxd to reveal the leaf sizes.
curl -s ${READ_URL}tile/entries/000.p/3 | xxd
```

Expand Down
4 changes: 0 additions & 4 deletions deployment/live/aws/conformance/ci/terragrunt.hcl
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
terraform {
source = "${get_repo_root()}/deployment/modules/aws//storage"
}

include "root" {
path = find_in_parent_folders()
expose = true
Expand Down
24 changes: 15 additions & 9 deletions deployment/live/aws/conformance/terragrunt.hcl
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
terraform {
source = "${get_repo_root()}/deployment/modules/aws//storage"
source = "${get_repo_root()}/deployment/modules/aws//conformance"
}

locals {
env = path_relative_to_include()
account_id = "${get_aws_account_id()}"
region = get_env("AWS_REGION", "us-east-1")
profile = get_env("AWS_PROFILE", "default")
base_name = get_env("TESSERA_BASE_NAME", "${local.env}-conformance")
prefix_name = get_env("TESSERA_PREFIX_NAME", "trillian-tessera")
ephemeral = true
env = path_relative_to_include()
account_id = "${get_aws_account_id()}"
region = get_env("AWS_REGION", "us-east-1")
base_name = get_env("TESSERA_BASE_NAME", "${local.env}-conformance")
prefix_name = get_env("TESSERA_PREFIX_NAME", "trillian-tessera")
ecr_registry = get_env("ECR_REGISTRY", "${local.account_id}.dkr.ecr.${local.region}.amazonaws.com")
ecr_repository_conformance = get_env("ECR_REPOSITORY_CONFORMANCE", "trillian-tessera/conformance:latest")
ecr_repository_hammer = get_env("ECR_REPOSITORY_HAMMER", "trillian-tessera/hammer:latest")
signer = get_env("TESSERA_SIGNER")
verifier = get_env("TESSERA_VERIFIER")
# Roles are defined externally
ecs_execution_role = "arn:aws:iam::864981736166:role/ecsTaskExecutionRole"
ecs_conformance_task_role = "arn:aws:iam::864981736166:role/ConformanceECSTaskRolePolicy"
ephemeral = true
}

remote_state {
backend = "s3"

config = {
region = local.region
profile = local.profile
bucket = "${local.prefix_name}-${local.base_name}-terraform-state"
key = "${local.env}/terraform.tfstate"
dynamodb_table = "${local.prefix_name}-${local.base_name}-terraform-lock"
Expand Down
Loading

0 comments on commit a1eb16a

Please sign in to comment.