371 lines
6.8 KiB
Markdown
371 lines
6.8 KiB
Markdown
# aws-localstack
|
|
|
|
OpenTofu project for provisioning AWS resources on LocalStack for the Quantum application.
|
|
|
|
LocalStack endpoint:
|
|
|
|
```text
|
|
https://localstack.paulononato.com.br
|
|
```
|
|
|
|
## Resources
|
|
|
|
- S3 bucket for Quantum application artifacts.
|
|
- SQS main queue and DLQ.
|
|
- Python Lambda function for event processing.
|
|
- IAM role and policies for the Lambda function.
|
|
- CloudWatch Log Group.
|
|
- Secrets Manager secret with application configuration.
|
|
- Event source mapping SQS -> Lambda.
|
|
- Nginx container serving the Quantum application screen through Traefik.
|
|
|
|
Default resource names for the `dev` environment:
|
|
|
|
```text
|
|
quantum-dev-artifacts
|
|
quantum-dev-events
|
|
quantum-dev-events-dlq
|
|
quantum-dev-processor
|
|
/aws/lambda/quantum-dev-processor
|
|
quantum-dev/app
|
|
```
|
|
|
|
## Repository Layout
|
|
|
|
```text
|
|
.
|
|
+-- environments
|
|
| +-- dev
|
|
| +-- stg
|
|
| +-- prd
|
|
+-- examples
|
|
+-- modules
|
|
+-- quantum
|
|
```
|
|
|
|
Each environment is an independent OpenTofu root module. The shared infrastructure code lives in `modules/quantum`.
|
|
|
|
## Prerequisites
|
|
|
|
- OpenTofu installed.
|
|
- AWS CLI, optional for testing.
|
|
- Access to the LocalStack endpoint.
|
|
|
|
Credentials used by LocalStack:
|
|
|
|
```bash
|
|
export AWS_ACCESS_KEY_ID=test
|
|
export AWS_SECRET_ACCESS_KEY=test
|
|
export AWS_DEFAULT_REGION=us-east-1
|
|
```
|
|
|
|
On PowerShell:
|
|
|
|
```powershell
|
|
$env:AWS_ACCESS_KEY_ID="test"
|
|
$env:AWS_SECRET_ACCESS_KEY="test"
|
|
$env:AWS_DEFAULT_REGION="us-east-1"
|
|
```
|
|
|
|
## Usage
|
|
|
|
Choose an environment first:
|
|
|
|
```bash
|
|
cd environments/dev
|
|
```
|
|
|
|
Use `environments/stg` or `environments/prd` for the other stages.
|
|
|
|
Initialize:
|
|
|
|
```bash
|
|
tofu init
|
|
```
|
|
|
|
Plan:
|
|
|
|
```bash
|
|
tofu plan
|
|
```
|
|
|
|
Apply:
|
|
|
|
```bash
|
|
tofu apply
|
|
```
|
|
|
|
Destroy:
|
|
|
|
```bash
|
|
tofu destroy
|
|
```
|
|
|
|
## Docker Usage
|
|
|
|
You can run OpenTofu from a Docker container instead of installing it on the host.
|
|
|
|
Build the runner image:
|
|
|
|
```bash
|
|
docker compose build tofu
|
|
```
|
|
|
|
Run `init` for the default `dev` environment:
|
|
|
|
```bash
|
|
docker compose run --rm tofu init
|
|
```
|
|
|
|
Run `plan`:
|
|
|
|
```bash
|
|
docker compose run --rm tofu plan
|
|
```
|
|
|
|
Run `apply`:
|
|
|
|
```bash
|
|
docker compose run --rm tofu apply
|
|
```
|
|
|
|
Select another environment with `QUANTUM_ENV`:
|
|
|
|
```bash
|
|
QUANTUM_ENV=stg docker compose run --rm tofu plan
|
|
QUANTUM_ENV=prd docker compose run --rm tofu plan
|
|
```
|
|
|
|
On PowerShell:
|
|
|
|
```powershell
|
|
$env:QUANTUM_ENV="stg"
|
|
docker compose run --rm tofu plan
|
|
```
|
|
|
|
## Runtime Evidence
|
|
|
|
Use the commands below to prove that LocalStack, the Quantum application screen, and the provisioned resources are running.
|
|
|
|
The AWS resource evidence commands assume the selected environment has already been applied with `tofu apply` or `docker compose run --rm tofu apply`.
|
|
|
|
### LocalStack Health
|
|
|
|
```bash
|
|
curl -s https://localstack.paulononato.com.br/_localstack/health
|
|
```
|
|
|
|
Expected evidence:
|
|
|
|
```text
|
|
"edition": "community"
|
|
"s3": "available" or "s3": "running"
|
|
"sqs": "available"
|
|
"lambda": "available"
|
|
"iam": "available"
|
|
"logs": "available"
|
|
"secretsmanager": "available"
|
|
```
|
|
|
|
### OpenTofu State
|
|
|
|
From an environment directory, for example `environments/dev`:
|
|
|
|
```bash
|
|
tofu output
|
|
```
|
|
|
|
When using Docker from the repository root:
|
|
|
|
```bash
|
|
docker compose run --rm tofu output
|
|
```
|
|
|
|
Expected outputs:
|
|
|
|
```text
|
|
localstack_endpoint
|
|
quantum_bucket_name
|
|
quantum_queue_url
|
|
quantum_dlq_url
|
|
quantum_lambda_name
|
|
quantum_log_group_name
|
|
quantum_secret_name
|
|
```
|
|
|
|
### S3 Evidence
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br s3 ls
|
|
aws --endpoint-url https://localstack.paulononato.com.br s3 ls s3://$(tofu output -raw quantum_bucket_name)
|
|
```
|
|
|
|
Expected evidence:
|
|
|
|
```text
|
|
quantum-dev-artifacts
|
|
config/quantum-dev.json
|
|
```
|
|
|
|
### SQS Evidence
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br sqs list-queues
|
|
```
|
|
|
|
Send a message:
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br sqs send-message \
|
|
--queue-url "$(tofu output -raw quantum_queue_url)" \
|
|
--message-body file://../../examples/quantum-message.json
|
|
```
|
|
|
|
Expected evidence:
|
|
|
|
```text
|
|
quantum-dev-events
|
|
quantum-dev-events-dlq
|
|
MessageId
|
|
```
|
|
|
|
### Lambda Evidence
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br lambda list-functions
|
|
aws --endpoint-url https://localstack.paulononato.com.br lambda invoke \
|
|
--function-name quantum-dev-processor \
|
|
--invocation-type DryRun \
|
|
/tmp/quantum-lambda-dry-run.json
|
|
```
|
|
|
|
Expected evidence:
|
|
|
|
```text
|
|
quantum-dev-processor
|
|
StatusCode: 204
|
|
```
|
|
|
|
### IAM Evidence
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br iam get-role \
|
|
--role-name quantum-dev-lambda-role
|
|
|
|
aws --endpoint-url https://localstack.paulononato.com.br iam list-policies \
|
|
--scope Local
|
|
```
|
|
|
|
Expected evidence:
|
|
|
|
```text
|
|
quantum-dev-lambda-role
|
|
quantum-dev-lambda-policy
|
|
```
|
|
|
|
### CloudWatch Logs Evidence
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br logs describe-log-groups \
|
|
--log-group-name-prefix /aws/lambda/quantum-dev-processor
|
|
```
|
|
|
|
Expected evidence:
|
|
|
|
```text
|
|
/aws/lambda/quantum-dev-processor
|
|
```
|
|
|
|
### Secrets Manager Evidence
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br secretsmanager get-secret-value \
|
|
--secret-id "$(tofu output -raw quantum_secret_name)"
|
|
```
|
|
|
|
Expected evidence:
|
|
|
|
```text
|
|
quantum-dev/app
|
|
SecretString
|
|
```
|
|
|
|
### Application Screen Evidence
|
|
|
|
```bash
|
|
curl -s https://quantum.paulononato.com.br
|
|
```
|
|
|
|
Expected evidence:
|
|
|
|
```text
|
|
Hello Quantum
|
|
```
|
|
|
|
The Quantum screen includes action buttons and inspection buttons:
|
|
|
|
```text
|
|
Refresh Evidence
|
|
Write S3 Evidence
|
|
Send SQS Message
|
|
Check Lambda
|
|
Inspect S3
|
|
Inspect SQS
|
|
Inspect Lambda
|
|
Inspect IAM
|
|
Inspect Secret
|
|
Inspect Logs
|
|
```
|
|
|
|
The inspection buttons call the `quanto-api` backend and return live LocalStack data:
|
|
|
|
- `Inspect S3` lists objects in the Quantum bucket.
|
|
- `Inspect SQS` shows queue counters, DLQ counters, and a sample of visible messages.
|
|
- `Inspect Lambda` shows runtime, handler, state, environment variables, and event source mappings.
|
|
- `Inspect IAM` shows the Lambda role and attached policies.
|
|
- `Inspect Secret` shows the application secret metadata and current value.
|
|
- `Inspect Logs` shows the CloudWatch Log Group and recent log streams.
|
|
|
|
On the Docker Swarm host:
|
|
|
|
```bash
|
|
docker stack ls
|
|
docker service ls --filter name=quanto
|
|
docker service ps quanto_app
|
|
```
|
|
|
|
Expected evidence:
|
|
|
|
```text
|
|
quanto
|
|
quanto_app
|
|
1/1
|
|
```
|
|
|
|
## Quick Tests
|
|
|
|
List buckets:
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br s3 ls
|
|
```
|
|
|
|
Send a message to the Quantum queue:
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br sqs send-message \
|
|
--queue-url "$(tofu output -raw quantum_queue_url)" \
|
|
--message-body file://../../examples/quantum-message.json
|
|
```
|
|
|
|
Read the secret:
|
|
|
|
```bash
|
|
aws --endpoint-url https://localstack.paulononato.com.br secretsmanager get-secret-value \
|
|
--secret-id "$(tofu output -raw quantum_secret_name)"
|
|
```
|
|
|
|
## RDS Note
|
|
|
|
RDS is not included in the LocalStack Community edition provisioned on the server. This project avoids RDS and uses only the services available in the current stack.
|