Skip to content

Commit baf6f5a

Browse files
committed
Setup AWS Terraform configurations
1 parent 60e8a1b commit baf6f5a

File tree

11 files changed

+423
-39
lines changed

11 files changed

+423
-39
lines changed

deployment/live/aws/README.md

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,4 @@
11
# AWS live configs
22

3-
TODO: Add terraform configuration files.
4-
5-
## Temporary Dev Env Setup
6-
7-
### Create the MySQL database and user
8-
9-
```sh
10-
mysql -h tesseract.cluster-xxxx12345678.us-east-1.rds.amazonaws.com -u admin -p
11-
```
12-
13-
```sql
14-
CREATE DATABASE tesseract;
15-
CREATE USER 'tesseract'@'%' IDENTIFIED BY 'tesseract';
16-
GRANT ALL PRIVILEGES ON tesseract.* TO 'tesseract'@'%';
17-
FLUSH PRIVILEGES;
18-
```
19-
20-
### Create the S3 bucket
21-
22-
### Start the TesseraCT server
23-
24-
```sh
25-
export AWS_REGION=us-east-1
26-
export AWS_PROFILE=AdministratorAccess-<REDACTED>
27-
```
28-
29-
```sh
30-
go run ./cmd/aws \
31-
--http_endpoint=localhost:6962 \
32-
--roots_pem_file=./internal/testdata/fake-ca.cert \
33-
--origin=test-static-ct \
34-
--bucket=test-static-ct \
35-
--db_name=tesseract \
36-
--db_host=tesseract.cluster-xxxx12345678.us-east-1.rds.amazonaws.com \
37-
--db_port=3306 \
38-
--db_user=tesseract \
39-
--db_password=tesseract \
40-
--dedup_path=test-static-ct
41-
```
3+
This directory contains Terragrunt configs we use to run TesseraCT logs and other related pieces of infrastructure:
4+
- `test`: configures a test log using a EC2 VM

deployment/live/aws/terragrunt.hcl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
locals {
2+
env = path_relative_to_include()
3+
region = get_env("AWS_REGION", "us-east-1")
4+
base_name = get_env("TESSERA_BASE_NAME", "${local.env}-static-ct")
5+
origin_suffix = get_env("TESSERA_ORIGIN_SUFFIX", "")
6+
prefix_name = "${get_aws_account_id()}"
7+
ephemeral = true
8+
}
9+
10+
remote_state {
11+
backend = "s3"
12+
13+
config = {
14+
region = local.region
15+
bucket = "${local.prefix_name}-${local.base_name}-terraform-state"
16+
key = "terraform.tfstate"
17+
s3_bucket_tags = {
18+
name = "terraform_state_storage"
19+
}
20+
use_lockfile = true
21+
}
22+
}

deployment/live/aws/test/.terraform.lock.hcl

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

deployment/live/aws/test/README.md

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
# AWS TesseraCT Test Environment
2+
3+
> [!CAUTION]
4+
>
5+
> This test environment creates real Amazon Web Services resources running in your account. They will cost you real money. For the purposes of this demo, it is strongly recommended that you create a new account so that you can easily clean up at the end.
6+
7+
## Prerequisites
8+
9+
You'll need to have a EC2 Amazon Linux VM running in the same AWS account that you can SSH to,
10+
with [Go](https://go.dev/doc/install) and
11+
[terragrunt](https://terragrunt.gruntwork.io/docs/getting-started/install/)
12+
installed, and your favourite terminal multiplexer.
13+
14+
## Overview
15+
16+
This config uses the [aws/tesseract/test](/deployment/modules/aws/tesseract/test) module to
17+
define a test environment to run the TesseraCT, backed by Trillian Tessera.
18+
19+
At a high level, this environment consists of:
20+
- One RDS Aurora MySQL database
21+
- One S3 Bucket
22+
23+
## Manual deployment
24+
25+
Authenticate with a role that has sufficient access to create resources.
26+
For the purpose of this test environment, and for ease of demonstration, we'll use the
27+
`AdministratorAccess` role, and authenticate with `aws configure sso`.
28+
29+
**DO NOT** use this role to run any production infrastructure, or if there are
30+
*other services running on your AWS account.
31+
32+
```sh
33+
[ec2-user@ip static-ct]$ aws configure sso
34+
SSO session name (Recommended): greenfield-session
35+
SSO start URL [None]: https://console.aws.amazon.com/ // unless you use a custom signin console
36+
SSO region [None]: us-east-1
37+
SSO registration scopes [sso:account:access]:
38+
Attempting to automatically open the SSO authorization page in your default browser.
39+
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:
40+
41+
https://device.sso.us-east-1.amazonaws.com/
42+
43+
Then enter the code:
44+
45+
<REDACTED>
46+
There are 4 AWS accounts available to you.
47+
Using the account ID <REDACTED>
48+
The only role available to you is: AdministratorAccess
49+
Using the role name "AdministratorAccess"
50+
CLI default client Region [None]: us-east-1
51+
CLI default output format [None]:
52+
CLI profile name [AdministratorAccess-<REDACTED>]:
53+
54+
To use this profile, specify the profile name using --profile, as shown:
55+
56+
aws s3 ls --profile AdministratorAccess-<REDACTED>
57+
```
58+
59+
Set the required environment variables:
60+
61+
```bash
62+
export AWS_REGION={VALUE} # e.g: us-east-1
63+
export AWS_PROFILE=AdministratorAccess-<REDACTED>
64+
```
65+
66+
Terraforming the account can be done by:
67+
1. `cd` to the [/deployment/live/aws/test/](/deployment/live/aws/test/) to deploy/change.
68+
2. Run `terragrunt apply`.
69+
70+
Store the Aurora RDS database and S3 bucket information into the environment variables:
71+
72+
```sh
73+
export TESSERACT_DB_HOST=$(terragrunt output -raw rds_aurora_cluster_endpoint)
74+
export TESSERACT_DB_PASSWORD=$(aws secretsmanager get-secret-value --secret-id $(terragrunt output -json rds_aurora_cluster_master_user_secret | jq --raw-output .[0].secret_arn) --query SecretString --output text | jq --raw-output .password)
75+
export TESSERACT_BUCKET_NAME=$(terragrunt output -raw s3_bucket_name)
76+
```
77+
78+
Connect the VM and Aurora database following [these instructions](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/tutorial-ec2-rds-option1.html#option1-task3-connect-ec2-instance-to-rds-database), it takes a few clicks in the UI.
79+
80+
## Run the TesseraCT
81+
82+
### With fake chains
83+
84+
On the VM, run the following command to bring up the TesseraCT:
85+
86+
```bash
87+
go run ./cmd/aws \
88+
--http_endpoint=localhost:6962 \
89+
--roots_pem_file=./internal/testdata/fake-ca.cert \
90+
--origin=test-static-ct \
91+
--bucket=${TESSERACT_BUCKET_NAME} \
92+
--db_name=tesseract \
93+
--db_host=${TESSERACT_DB_HOST} \
94+
--db_port=3306 \
95+
--db_user=tesseract \
96+
--db_password=${TESSERACT_DB_PASSWORD} \
97+
--dedup_path=test-static-ct
98+
```
99+
100+
In a different terminal you can either mint and submit certificates manually, or
101+
use the [ct_hammer
102+
tool](https://github.com/google/certificate-transparency-go/blob/master/trillian/integration/ct_hammer/main.go)
103+
to do this.
104+
105+
#### Generate chains manually
106+
107+
Generate a chain manually. The password for the private key is `gently`:
108+
109+
```bash
110+
mkdir -p /tmp/httpschain
111+
openssl genrsa -out /tmp/httpschain/cert.key 2048
112+
openssl req -new -key /tmp/httpschain/cert.key -out /tmp/httpschain/cert.csr -config=internal/testdata/fake-ca.cfg
113+
openssl x509 -req -days 3650 -in /tmp/httpschain/cert.csr -CAkey internal/testdata/fake-ca.privkey.pem -CA internal/testdata/fake-ca.cert -outform pem -out /tmp/httpschain/chain.pem -provider legacy -provider default
114+
cat internal/testdata/fake-ca.cert >> /tmp/httpschain/chain.pem
115+
```
116+
117+
Finally, submit the chain to the TesseraCT:
118+
119+
```bash
120+
go run github.com/google/certificate-transparency-go/client/ctclient@master upload --cert_chain=/tmp/httpschain/chain.pem --skip_https_verify --log_uri=http://localhost:6962/test-static-ct
121+
```
122+
123+
#### Automatically generate chains
124+
125+
Save the TesseraCT repo's path:
126+
127+
```bash
128+
export TESSERACT_REPO=$(pwd)
129+
```
130+
131+
Clone the [certificate-transparency-go](https://github.com/google/certificate-transparency-go) repo, and from there run:
132+
133+
```bash
134+
go run ./trillian/integration/ct_hammer/ \
135+
--ct_http_servers=localhost:6962/${TESSERA_BASE_NAME} \
136+
--max_retry=2m \
137+
--invalid_chance=0 \
138+
--get_sth=0 \
139+
--get_sth_consistency=0 \
140+
--get_proof_by_hash=0 \
141+
--get_entries=0 \
142+
--get_roots=0 \
143+
--get_entry_and_proof=0 \
144+
--max_parallel_chains=4 \
145+
--skip_https_verify=true \
146+
--operations=10000 \
147+
--rate_limit=150 \
148+
--log_config=${TESSERACT_REPO}/testdata/hammer.cfg \
149+
--testdata_dir=./trillian/testdata/
150+
```
151+
152+
### With real HTTPS certificates
153+
154+
We'll run a TesseraCT and copy certificates from an existing RFC6962 log to it.
155+
It uses the [ct_hammer tool from certificate-transparency-go](https://github.com/google/certificate-transparency-go/tree/aceb1d4481907b00c087020a3930c7bd691a0110/trillian/integration/ct_hammer).
156+
157+
First, set a few environment variables:
158+
159+
```bash
160+
export TESSERACT_REPO=$(pwd)
161+
export SRC_LOG_URI=https://ct.googleapis.com/logs/xenon2022
162+
```
163+
164+
Then, get fetch the roots the source logs accepts, and edit configs accordingly.
165+
To do so, clone the [certificate-transparency-go](https://github.com/google/certificate-transparency-go) repo, and from there run:
166+
167+
```bash
168+
export CTGO_REPO=$(pwd)
169+
mkdir -p /tmp/hammercfg
170+
cp ${TESSERACT_REPO}/testdata/hammer.cfg /tmp/hammercfg
171+
go run ./client/ctclient get-roots --log_uri=${SRC_LOG_URI} --text=false > /tmp/hammercfg/roots.pem
172+
sed -i 's-""-"/tmp/hammercfg/roots.pem"-g' /tmp/hammercfg/hammer.cfg
173+
```
174+
175+
Run the TesseraCT with the same roots:
176+
177+
```bash
178+
cd ${TESSERACT_REPO}
179+
go run ./cmd/aws \
180+
--http_endpoint=localhost:6962 \
181+
--roots_pem_file=/tmp/hammercfg/roots.pem \
182+
--origin=test-static-ct \
183+
--bucket=${TESSERACT_BUCKET_NAME} \
184+
--db_name=tesseract \
185+
--db_host=${TESSERACT_DB_HOST} \
186+
--db_port=3306 \
187+
--db_user=tesseract \
188+
--db_password=${TESSERACT_DB_PASSWORD} \
189+
--dedup_path=test-static-ct
190+
-v=3
191+
```
192+
193+
Run `ct_hammer` in a different terminal:
194+
195+
```bash
196+
cd ${CTGO_REPO}
197+
go run ./trillian/integration/ct_hammer/ \
198+
--ct_http_servers=localhost:6962/test-static-ct \
199+
--max_retry=2m \
200+
--invalid_chance=0 \
201+
--get_sth=0 \
202+
--get_sth_consistency=0 \
203+
--get_proof_by_hash=0 \
204+
--get_entries=0 \
205+
--get_roots=0 \
206+
--get_entry_and_proof=0 \
207+
--max_parallel_chains=4 \
208+
--skip_https_verify=true \
209+
--operations=10000 \
210+
--rate_limit=150 \
211+
--log_config=/tmp/hammercfg/hammer.cfg \
212+
--src_log_uri=${SRC_LOG_URI}
213+
```
214+
215+
> [!IMPORTANT]
216+
> Do not forget to delete all the resources to avoid incuring any further cost
217+
> when you're done using the log. The easiest way to do this, is to [close the account](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-closing.html).
218+
> If you prefer to delete the resources with `terragrunt destroy`, bear in mind
219+
> that this command might not destroy all the resources that were created (like
220+
> the S3 bucket or DynamoDB instance Terraform created to store its state for
221+
> instance). If `terragrunt destroy` shows no output, run
222+
> `terragrunt destroy --terragrunt-log-level debug --terragrunt-debug`.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
terraform {
2+
source = "${get_repo_root()}/deployment/modules/aws//tesseract/test"
3+
}
4+
5+
locals {
6+
env = "test"
7+
base_name = get_env("TESSERA_BASE_NAME", "${local.env}-static-ct")
8+
ephemeral = true
9+
}
10+
11+
include "root" {
12+
path = find_in_parent_folders()
13+
expose = true
14+
}
15+
16+
inputs = merge(
17+
local,
18+
include.root.locals,
19+
)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
version = "5.92.0"
6+
}
7+
}
8+
}
9+
10+
# Configure the AWS Provider
11+
provider "aws" {
12+
region = var.region
13+
}
14+
15+
resource "aws_s3_bucket" "log_bucket" {
16+
bucket = "${var.prefix_name}-${var.base_name}-bucket"
17+
18+
force_destroy = var.ephemeral
19+
}
20+
21+
resource "aws_rds_cluster" "log_rds_cluster" {
22+
cluster_identifier = "${var.base_name}-cluster"
23+
engine = "aurora-mysql"
24+
engine_version = "8.0.mysql_aurora.3.05.2"
25+
database_name = "tesseract"
26+
manage_master_user_password = true
27+
master_username = "tesseract"
28+
skip_final_snapshot = true
29+
apply_immediately = true
30+
}
31+
32+
resource "aws_rds_cluster_instance" "cluster_instances" {
33+
count = 1
34+
cluster_identifier = aws_rds_cluster.log_rds_cluster.id
35+
instance_class = "db.r5.large"
36+
engine = aws_rds_cluster.log_rds_cluster.engine
37+
engine_version = aws_rds_cluster.log_rds_cluster.engine_version
38+
identifier = "${var.base_name}-${count.index + 1}"
39+
40+
force_destroy = var.ephemeral
41+
}

0 commit comments

Comments
 (0)