From fe1f674edff4a5b3b48476781a6cadc843e65f49 Mon Sep 17 00:00:00 2001 From: Philippe Boneff Date: Mon, 2 Dec 2024 10:03:40 +0000 Subject: [PATCH 1/4] Terraform+Terragrunt+Doc to launch tessera from a VM --- deployment/live/aws/codelab/README.md | 66 +++++++++++++++++ deployment/live/aws/codelab/terragrunt.hcl | 26 +++++++ deployment/modules/aws/codelab/main.tf | 79 +++++++++++++++++++++ deployment/modules/aws/codelab/outputs.tf | 9 +++ deployment/modules/aws/codelab/variables.tf | 19 +++++ deployment/modules/aws/storage/main.tf | 14 +--- deployment/modules/aws/storage/outputs.tf | 9 +++ 7 files changed, 209 insertions(+), 13 deletions(-) create mode 100644 deployment/live/aws/codelab/README.md create mode 100644 deployment/live/aws/codelab/terragrunt.hcl create mode 100644 deployment/modules/aws/codelab/main.tf create mode 100644 deployment/modules/aws/codelab/outputs.tf create mode 100644 deployment/modules/aws/codelab/variables.tf create mode 100644 deployment/modules/aws/storage/outputs.tf diff --git a/deployment/live/aws/codelab/README.md b/deployment/live/aws/codelab/README.md new file mode 100644 index 00000000..6e4b3aae --- /dev/null +++ b/deployment/live/aws/codelab/README.md @@ -0,0 +1,66 @@ +# AWS Test Configs + +Work in progress. + + + 1. SSH to a VM + 2. Install golang + 3. Install git + 4. Install terragrunt? + 5. Install terragrunt + 6. Install Terminal multiplexer + 7. run `aws configure sso`. Here's an example run: + ``` + [ec2-user@ip-172-31-21-186 trillian-tessera]$ aws configure sso + SSO session name (Recommended): greenfield-session + SSO start URL [None]: https://console.aws.amazon.com/ // unless you use a custom signin console + SSO region [None]: us-east-1 + SSO registration scopes [sso:account:access]: + Attempting to automatically open the SSO authorization page in your default browser. + If the browser does not open or you wish to use a different device to authorize this request, open the following URL: + + https://device.sso.us-east-1.amazonaws.com/ + + Then enter the code: + + + There are 4 AWS accounts available to you. + Using the account ID + The only role available to you is: AdministratorAccess + Using the role name "AdministratorAccess" + CLI default client Region [None]: us-east-1 + CLI default output format [None]: + CLI profile name [AdministratorAccess-]: + + To use this profile, specify the profile name using --profile, as shown: + + aws s3 ls --profile AdministratorAccess- + ``` + 8. Set environment variables: + `export AWS_REGION=us-east-1` + `export AWS_PROFILE=AdministratorAccess-` + 9. `git clone https://github.com/transparency-dev/trillian-tessera` + 10. `cd trillian-tessera/deployment/live/aws/codelab` + 11. `terragrunt init` + 12. `terragrunt apply` + 13. save variables for later + ``` + export LOG_BUCKET=$(terragrunt output -raw log_bucket_id) + export LOG_RDS_DB=$(terragrunt output -raw log_rds_db) + ``` + 14. Use the UI to connect the VM to the DB instance: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/tutorial-ec2-rds-option3.html + 15. generate keys + ``` + mkdir -p ~/tessera-keys + go run github.com/transparency-dev/serverless-log/cmd/generate_keys@80334bc9dc573e8f6c5b3694efad6358da50abd4 \ + --key_name=$TESSERA_PREFIX_NAME-$TESSERA_BASE_NAME/test/conformance \ + --out_priv=/home/ec2-user/tessera-keys/key.sec \ + --out_pub=/home/ec2-user/tessera-keys/key.pub + ``` + 16. Run the conformance binary from within `trillian-tessera/cmd/conformance/aws` + ``` + go run ./ --bucket=$LOG_BUCKET --db_user=root --db_password=password --db_name=tessera --db_host=$LOG_RDS_DB --signer=$(cat /home/ec2-user/tessera-keys/key.sec) -v=3 + ``` + 17. export WRITE_URL=http://localhost:2024/ + 18. export READ_URL=https://$LOG_BUCKET.s3.$AWS_REGION.amazonaws.com/ + 19. Follow the codelab: https://github.com/transparency-dev/trillian-tessera/tree/main/cmd/conformance#codelab to send leaves. diff --git a/deployment/live/aws/codelab/terragrunt.hcl b/deployment/live/aws/codelab/terragrunt.hcl new file mode 100644 index 00000000..3103371c --- /dev/null +++ b/deployment/live/aws/codelab/terragrunt.hcl @@ -0,0 +1,26 @@ +terraform { + source = "${get_repo_root()}/deployment/modules/aws//codelab" +} + +locals { + region = get_env("AWS_REGION", "us-east-1") + base_name = "trillian-tessera" + prefix_name = "codelab-${get_aws_account_id()}" + ephemeral = true +} + +remote_state { + backend = "s3" + + config = { + region = local.region + bucket = "${local.prefix_name}-${local.base_name}-terraform-state" + key = "terraform.tfstate" + dynamodb_table = "${local.prefix_name}-${local.base_name}-terraform-lock" + s3_bucket_tags = { + name = "terraform_state_storage" + } + } +} + +inputs = local diff --git a/deployment/modules/aws/codelab/main.tf b/deployment/modules/aws/codelab/main.tf new file mode 100644 index 00000000..f882cd5e --- /dev/null +++ b/deployment/modules/aws/codelab/main.tf @@ -0,0 +1,79 @@ +# Header ###################################################################### +terraform { + backend "s3" {} + required_providers { + aws = { + source = "hashicorp/aws" + version = "5.76.0" + } + } +} + +locals { + name = "${var.prefix_name}-${var.base_name}" + port = 2024 +} + +provider "aws" { + region = var.region +} + +module "storage" { + source = "../storage" + + prefix_name = var.prefix_name + base_name = var.base_name + region = var.region + ephemeral = true +} + +# Resources #################################################################### +## Virtual private network ##################################################### +# This will be used for the containers to communicate between themselves, and +# the S3 bucket. +resource "aws_default_vpc" "default" { + tags = { + Name = "Default VPC" + } +} + +## Connect S3 bucket to VPC #################################################### +# This allows the hammer to talk to a non public S3 bucket over HTTP. +resource "aws_vpc_endpoint" "s3" { + vpc_id = aws_default_vpc.default.id + service_name = "com.amazonaws.${var.region}.s3" +} + +resource "aws_vpc_endpoint_route_table_association" "private_s3" { + vpc_endpoint_id = aws_vpc_endpoint.s3.id + route_table_id = aws_default_vpc.default.default_route_table_id +} + +resource "aws_s3_bucket_policy" "allow_access_from_vpce" { + bucket = module.storage.log_bucket.id + policy = data.aws_iam_policy_document.allow_access_from_vpce.json +} + +data "aws_iam_policy_document" "allow_access_from_vpce" { + statement { + principals { + type = "*" + identifiers = ["*"] + } + + actions = [ + "s3:GetObject", + ] + + resources = [ + "${module.storage.log_bucket.arn}/*", + ] + + condition { + test = "StringEquals" + variable = "aws:sourceVpce" + values = [aws_vpc_endpoint.s3.id] + } + } + depends_on = [aws_vpc_endpoint.s3] +} diff --git a/deployment/modules/aws/codelab/outputs.tf b/deployment/modules/aws/codelab/outputs.tf new file mode 100644 index 00000000..d9914268 --- /dev/null +++ b/deployment/modules/aws/codelab/outputs.tf @@ -0,0 +1,9 @@ +output "log_bucket_id" { + description = "Log S3 bucket name" + value = module.storage.log_bucket.id +} + +output "log_rds_db" { + description = "Log RDS database endpoint" + value = module.storage.log_rds_db.endpoint +} diff --git a/deployment/modules/aws/codelab/variables.tf b/deployment/modules/aws/codelab/variables.tf new file mode 100644 index 00000000..805a2644 --- /dev/null +++ b/deployment/modules/aws/codelab/variables.tf @@ -0,0 +1,19 @@ +variable "prefix_name" { + description = "Common prefix to use when naming resources, ensures unicity of the s3 bucket name." + type = string +} + +variable "base_name" { + description = "Common name to use when naming resources." + type = string +} + +variable "region" { + description = "Region in which to create resources." + type = string +} + +variable "ephemeral" { + description = "Set to true if this is a throwaway/temporary log instance. Will set attributes on created resources to allow them to be disabled/deleted more easily." + type = bool +} diff --git a/deployment/modules/aws/storage/main.tf b/deployment/modules/aws/storage/main.tf index 04c7c992..3378d77e 100644 --- a/deployment/modules/aws/storage/main.tf +++ b/deployment/modules/aws/storage/main.tf @@ -1,15 +1,3 @@ -terraform { - backend "s3" {} - required_providers { - aws = { - source = "hashicorp/aws" - version = "5.76.0" - } - } -} - -data "aws_caller_identity" "current" {} - locals { name = "${var.prefix_name}-${var.base_name}" } @@ -39,7 +27,7 @@ resource "aws_rds_cluster" "log_rds" { # TODO(phboneff): move to either random strings / Secret Manager / IAM master_password = "password" skip_final_snapshot = true - backup_retention_period = 0 + backup_retention_period = 1 } resource "aws_rds_cluster_instance" "cluster_instances" { diff --git a/deployment/modules/aws/storage/outputs.tf b/deployment/modules/aws/storage/outputs.tf new file mode 100644 index 00000000..20b78903 --- /dev/null +++ b/deployment/modules/aws/storage/outputs.tf @@ -0,0 +1,9 @@ +output "log_bucket" { + description = "Log S3 bucket" + value = aws_s3_bucket.log_bucket +} + +output "log_rds_db" { + description = "Log RDS database" + value = aws_rds_cluster.log_rds +} From 9a53c2ff679f039d7ec17844973c125079ef9478 Mon Sep 17 00:00:00 2001 From: Philippe Boneff Date: Mon, 2 Dec 2024 12:00:07 +0000 Subject: [PATCH 2/4] better instructions --- deployment/live/aws/codelab/README.md | 115 +++++++++++++++------- deployment/modules/aws/codelab/outputs.tf | 5 + 2 files changed, 83 insertions(+), 37 deletions(-) diff --git a/deployment/live/aws/codelab/README.md b/deployment/live/aws/codelab/README.md index 6e4b3aae..8750d5ac 100644 --- a/deployment/live/aws/codelab/README.md +++ b/deployment/live/aws/codelab/README.md @@ -1,15 +1,31 @@ -# AWS Test Configs +# AWS codelab deployment -Work in progress. +This codelab helps you bring a test Trillian Tessera stack on AWS, +and to use it running a test personality server on an EC2 VM. +The Tessera test stack will be comprised of an Aurora RDS MySQL database +and a private S3 bubket. This codelab will also guide you to connect both +the RDS instance and the S3 bucket to your VM. + +## Prerequisites +For the remainder of this codelab, you'll need to have an AWS account, +with a running EC2 Amazon Linux VM, and the following software installed: + - [golang](https://go.dev/doc/install), which we'll use to compile and + run the test personality on the VM + - [terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) + and [terragrunt](https://terragrunt.gruntwork.io/docs/getting-started/install/) + in order to deploy the Trillian Tessera stack from the VM. + - `git` to clone the repo + - a terminal multiplexer of your choice for convenience +## Instructions - 1. SSH to a VM - 2. Install golang - 3. Install git - 4. Install terragrunt? - 5. Install terragrunt - 6. Install Terminal multiplexer - 7. run `aws configure sso`. Here's an example run: + 1. SSH to your VM + 1. Authenticate with a role that has sufficient access to create resources. + For the purpose of this codelab, and for ease of demonstration, we'll use + the `AdministratorAccess` role, and authenticate with `aws configure sso`. + DO NOT use this role to run any production software, or if there are other + services running on your AWS account. + Here's an example run: ``` [ec2-user@ip-172-31-21-186 trillian-tessera]$ aws configure sso SSO session name (Recommended): greenfield-session @@ -36,31 +52,56 @@ Work in progress. aws s3 ls --profile AdministratorAccess- ``` - 8. Set environment variables: - `export AWS_REGION=us-east-1` - `export AWS_PROFILE=AdministratorAccess-` - 9. `git clone https://github.com/transparency-dev/trillian-tessera` - 10. `cd trillian-tessera/deployment/live/aws/codelab` - 11. `terragrunt init` - 12. `terragrunt apply` - 13. save variables for later - ``` - export LOG_BUCKET=$(terragrunt output -raw log_bucket_id) - export LOG_RDS_DB=$(terragrunt output -raw log_rds_db) - ``` - 14. Use the UI to connect the VM to the DB instance: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/tutorial-ec2-rds-option3.html - 15. generate keys - ``` - mkdir -p ~/tessera-keys - go run github.com/transparency-dev/serverless-log/cmd/generate_keys@80334bc9dc573e8f6c5b3694efad6358da50abd4 \ - --key_name=$TESSERA_PREFIX_NAME-$TESSERA_BASE_NAME/test/conformance \ - --out_priv=/home/ec2-user/tessera-keys/key.sec \ - --out_pub=/home/ec2-user/tessera-keys/key.pub - ``` - 16. Run the conformance binary from within `trillian-tessera/cmd/conformance/aws` - ``` - go run ./ --bucket=$LOG_BUCKET --db_user=root --db_password=password --db_name=tessera --db_host=$LOG_RDS_DB --signer=$(cat /home/ec2-user/tessera-keys/key.sec) -v=3 - ``` - 17. export WRITE_URL=http://localhost:2024/ - 18. export READ_URL=https://$LOG_BUCKET.s3.$AWS_REGION.amazonaws.com/ - 19. Follow the codelab: https://github.com/transparency-dev/trillian-tessera/tree/main/cmd/conformance#codelab to send leaves. + 1. Set these environment variables according to the you chose when configuring + your AWS profile: + ``` + export AWS_REGION=us-east-1 + export AWS_PROFILE=AdministratorAccess- + ``` + 1. Fetch the Tessera repo: + ``` + git clone https://github.com/transparency-dev/trillian-tessera + ``` + 1. Init terragrunt: + ``` + terragrunt init --terragrunt-working-dir=deployment/live/aws/codelab/ + ``` + 1. Apply everything: + ``` + terragrunt apply --terragrunt-working-dir=deployment/live/aws/codelab/ + ``` + This brings up the Terraform infrastructure (S3 bucket + dynanoDB table + for locking) and the Trillian Tessera stack: an RDS Aurora instance, + a private S3 bucket, and connects this bucket to the default VPC. + 1. Save the RDS instance URI and S3 bucket name for later: + ``` + export LOG_RDS_DB=$(terragrunt output --terragrunt-working-dir=deployment/live/aws/codelab/ --raw log_rds_db) + export LOG_BUCKET=$(terragrunt output --terragrunt-working-dir=deployment/live/aws/codelab/ --raw log_bucket_id) + export LOG_NAME=$(terragrunt output --terragrunt-working-dir=deployment/live/aws/codelab/ --raw log_name) + ``` + 1. Configure the VM and RDS instance to be able to speak to one another following + [these instructions](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/tutorial-ec2-rds-option3.html), + it takes a few clicks in the UI. + 1. Generate the key pair used to sign and verify checkpoints: + ``` + mkdir -p /home/ec2-user/tessera-keys + go run github.com/transparency-dev/serverless-log/cmd/generate_keys@80334bc9dc573e8f6c5b3694efad6358da50abd4 \ + --key_name=$LOG_NAME/test/conformance \ + --out_priv=/home/ec2-user/tessera-keys/$LOG_NAME.sec \ + --out_pub=/home/ec2-user/tessera-keys/$LOG_NAME.pub + ``` + 1. Run the conformance binary in `trillian-tessera/cmd/conformance/aws`. + This binary is a small personality that accepts `add/` requests, + and stores the data in the Trillian Tessera infrastructure you've + just brought up: + ``` + go run ./cmd/conformance/aws --bucket=$LOG_BUCKET --db_user=root --db_password=password --db_name=tessera --db_host=$LOG_RDS_DB --signer=$(cat /home/ec2-user/tessera-keys/$LOG_NAME.sec) -v=3 + ``` + 1. Congratulations, you've now successfully brought up a Trillian Tessera + stack on AWS, and started a personality server that can add entries to it. + This server accepts `add/` requests at `WRITE_URL=http://localhost:2024/`. + Log entries can be read directly from S3 without going through the server, + at `READ_URL=https://$LOG_BUCKET.s3.$AWS_REGION.amazonaws.com/` + 1. Head over to the [remainder of this codelab](https://github.com/transparency-dev/trillian-tessera/tree/main/cmd/conformance#codelab) + add leaves to the log. + \ No newline at end of file diff --git a/deployment/modules/aws/codelab/outputs.tf b/deployment/modules/aws/codelab/outputs.tf index d9914268..86c5592e 100644 --- a/deployment/modules/aws/codelab/outputs.tf +++ b/deployment/modules/aws/codelab/outputs.tf @@ -7,3 +7,8 @@ output "log_rds_db" { description = "Log RDS database endpoint" value = module.storage.log_rds_db.endpoint } + +output "log_name" { + description = "Log name" + value = local.name +} From d6bccc7f5ade947814e3c372f945cb2886ec115a Mon Sep 17 00:00:00 2001 From: Philippe Boneff Date: Mon, 2 Dec 2024 15:12:33 +0000 Subject: [PATCH 3/4] link codelab to it --- cmd/conformance/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/conformance/README.md b/cmd/conformance/README.md index 5b07b554..86caa4a6 100644 --- a/cmd/conformance/README.md +++ b/cmd/conformance/README.md @@ -9,6 +9,7 @@ Implementations are provided that use: - [A local filesystem](./posix/) - [MySQL](./mysql/) - [GCP](./gcp/) + - [AWS](deployment/live/aws/codelab/) 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. From 23696707864e3040f0ca686d593147c4b28e95fb Mon Sep 17 00:00:00 2001 From: Philippe Boneff Date: Mon, 2 Dec 2024 15:52:50 +0000 Subject: [PATCH 4/4] address comments --- deployment/live/aws/codelab/README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/deployment/live/aws/codelab/README.md b/deployment/live/aws/codelab/README.md index 8750d5ac..08cf0c8b 100644 --- a/deployment/live/aws/codelab/README.md +++ b/deployment/live/aws/codelab/README.md @@ -3,7 +3,7 @@ This codelab helps you bring a test Trillian Tessera stack on AWS, and to use it running a test personality server on an EC2 VM. The Tessera test stack will be comprised of an Aurora RDS MySQL database -and a private S3 bubket. This codelab will also guide you to connect both +and a private S3 bucket. This codelab will also guide you to connect both the RDS instance and the S3 bucket to your VM. ## Prerequisites @@ -52,7 +52,7 @@ with a running EC2 Amazon Linux VM, and the following software installed: aws s3 ls --profile AdministratorAccess- ``` - 1. Set these environment variables according to the you chose when configuring + 1. Set these environment variables according to the ones you chose when configuring your AWS profile: ``` export AWS_REGION=us-east-1 @@ -62,7 +62,7 @@ with a running EC2 Amazon Linux VM, and the following software installed: ``` git clone https://github.com/transparency-dev/trillian-tessera ``` - 1. Init terragrunt: + 1. From the root of the trillian-tessera repo, init terragrunt: ``` terragrunt init --terragrunt-working-dir=deployment/live/aws/codelab/ ``` @@ -70,9 +70,10 @@ with a running EC2 Amazon Linux VM, and the following software installed: ``` terragrunt apply --terragrunt-working-dir=deployment/live/aws/codelab/ ``` - This brings up the Terraform infrastructure (S3 bucket + dynanoDB table - for locking) and the Trillian Tessera stack: an RDS Aurora instance, - a private S3 bucket, and connects this bucket to the default VPC. + This brings up the Terraform infrastructure (S3 bucket + DynamoDB table + for terraform state locking only) and the Trillian Tessera stack: an RDS + Aurora instance, a private S3 bucket, and connects this bucket to the + default VPC. 1. Save the RDS instance URI and S3 bucket name for later: ``` export LOG_RDS_DB=$(terragrunt output --terragrunt-working-dir=deployment/live/aws/codelab/ --raw log_rds_db) @@ -86,7 +87,7 @@ with a running EC2 Amazon Linux VM, and the following software installed: ``` mkdir -p /home/ec2-user/tessera-keys go run github.com/transparency-dev/serverless-log/cmd/generate_keys@80334bc9dc573e8f6c5b3694efad6358da50abd4 \ - --key_name=$LOG_NAME/test/conformance \ + --key_name=$LOG_NAME \ --out_priv=/home/ec2-user/tessera-keys/$LOG_NAME.sec \ --out_pub=/home/ec2-user/tessera-keys/$LOG_NAME.pub ``` @@ -103,5 +104,5 @@ with a running EC2 Amazon Linux VM, and the following software installed: Log entries can be read directly from S3 without going through the server, at `READ_URL=https://$LOG_BUCKET.s3.$AWS_REGION.amazonaws.com/` 1. Head over to the [remainder of this codelab](https://github.com/transparency-dev/trillian-tessera/tree/main/cmd/conformance#codelab) - add leaves to the log. + to add leaves to the log. \ No newline at end of file