Skip to content
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

feat(deploy): add terraform configs #25

Merged
merged 4 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
TF_WORKSPACE=
TF_VAR_PRIVATE_KEY=
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@

/cmd/indexing-service
/indexing-service
*.car
*.car
/build
deploy/.terraform
.env
.tfworkspace
/ucangen
67 changes: 67 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
ifneq (,$(wildcard ./.env))
include .env
export
else
$(error You haven't setup your .env file. Please refer to the readme)
endif
GOOS=linux
GOARCH=arm64
GOCC?=go
GOFLAGS=-tags=lambda.norpc
CGO_ENABLED=0
LAMBDAS=build/getclaims/bootstrap build/getroot/bootstrap build/notifier/bootstrap build/postclaims/bootstrap build/providercache/bootstrap build/remotesync/bootstrap

ucangen:
go build -o ./ucangen cmd/ucangen/main.go

.PHONY: ucankey

ucankey: ucangen
./ucangen

.PHONY: clean-lambda

clean-lambda:
rm -rf build

.PHONY: clean-terraform

clean-terraform:
tofu -chdir=deploy destroy

.PHONY: clean

clean: clean-lambda clean-terraform

lambdas: $(LAMBDAS)

.PHONY: $(LAMBDAS)

$(LAMBDAS): build/%/bootstrap:
GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=$(CGO_ENABLED) $(GOCC) build $(GOFLAGS) -o $@ cmd/lambda/$*/main.go

deploy/.terraform:
tofu -chdir=deploy init

.tfworkspace:
tofu -chdir=deploy workspace new $(TF_WORKSPACE)
touch .tfworkspace

.PHONY: init

init: deploy/.terraform .tfworkspace

.PHONY: validate

validate: deploy/.terraform .tfworkspace
tofu -chdir=deploy validate

.PHONY: plan

plan: deploy/.terraform .tfworkspace $(LAMBDAS)
tofu -chdir=deploy plan

.PHONY: apply

apply: deploy/.terraform .tfworkspace $(LAMBDAS)
tofu -chdir=deploy apply
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

* [Overview](#overview)
* [Installation](#installation)
* [Deployment](#deployment)
* [Contribute](#contribute)
* [License](#license)

Expand All @@ -23,6 +24,46 @@ $ go install github.com/storacha/indexing-service/cmd@latest
...
```

## Deployment

Deployment of this service to AWS is managed by terraform which you can invoke with make.

### .env

You need to first generate a .env with relevant vars. Copy `.env.local` to `.env` and then set the following environment variables:

#### TF_WORKSPACE

Best to set this to your name. "prod" and "staging" are reserved for shared deployments

#### TF_VAR_private_key

This is a multibase encoded ed25519 private key used to sign receipts and for the indexer's peer ID. For development, you can generate one by running `make ucankey`

### Deployment commands

Note that these commands will call needed prerequisites -- `make apply` will essentially do all of these start to finish.

#### make lambdas

This will simply compile the lambdas locally and put then in the `build` directory

#### make init

You should only need to run this once -- initializes your terraform deployment and workspace. Make sure you've set TF_WORKSPACE first!

#### make validate

This will validate your terraform configuration -- good to run to check errors in any changes you make to terraform configs

#### make plan

This will plan a deployment, but not execute it -- useful to see ahead what changes will happen when you run the next deployment

#### make apply

The big kahuna! This will deploy all of your changes, including redeploying lambdas if any of code changes

## Contribute

Early days PRs are welcome!
Expand Down
Binary file added bootstrap
Binary file not shown.
25 changes: 25 additions & 0 deletions cmd/ucangen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package main

import (
"fmt"
"os"

ed25519 "github.com/storacha/go-ucanto/principal/ed25519/signer"
)

func main() {
signer, err := ed25519.Generate()
if err != nil {
fmt.Println(err)
os.Exit(-1)
}

asString, err := ed25519.Format(signer)
if err != nil {
fmt.Println(err)
os.Exit(-1)
}

fmt.Printf("# %s\n", signer.DID().String())
fmt.Println(asString)
}
37 changes: 37 additions & 0 deletions deploy/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions deploy/dynamodb.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
resource "aws_dynamodb_table" "metadata" {
name = "${terraform.workspace}-${var.app}-metadata"
billing_mode = "PAY_PER_REQUEST"

attribute {
name = "provider"
type = "S"
}

attribute {
name = "contextID"
type = "B"
}

hash_key = "provider"
range_key = "contextID"

tags = {
Name = "${terraform.workspace}-${var.app}-metadata"
}
}

resource "aws_dynamodb_table" "chunk_links" {
name = "${terraform.workspace}-${var.app}-chunk-links"
billing_mode = "PAY_PER_REQUEST"

attribute {
name = "provider"
type = "S"
}

attribute {
name = "contextID"
type = "B"
}

hash_key = "provider"
range_key = "contextID"

tags = {
Name = "${terraform.workspace}-${var.app}-chunk-links"
}
}
84 changes: 84 additions & 0 deletions deploy/elasticcache.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
locals {
caches = toset(["providers","indexes","claims"])
}
resource "aws_kms_key" "cache_key" {
description = "KMS CMK for ${terraform.workspace} ${var.app}"
enable_key_rotation = true
}

resource "aws_elasticache_serverless_cache" "cache" {
for_each = local.caches

engine = "redis"
name = "${terraform.workspace}-${var.app}-${each.key}-cache"
cache_usage_limits {
data_storage {
maximum = terraform.workspace == "prod" ? 10 : 1
unit = "GB"
}
ecpu_per_second {
maximum = terraform.workspace == "prod" ? 10000 : 1000
}
}
daily_snapshot_time = "02:00"
description = "${terraform.workspace} ${var.app} ${each.key} serverless cluster"
kms_key_id = aws_kms_key.cache_key.arn
major_engine_version = "7"
security_group_ids = [aws_security_group.cache_security_group.id]

snapshot_retention_limit = 7
subnet_ids = aws_subnet.vpc_private_subnet[*].id

user_group_id = aws_elasticache_user_group.cache_user_group.user_group_id
}

resource "aws_elasticache_user_group" "cache_user_group" {
engine = "REDIS"
user_group_id = "${terraform.workspace}-${var.app}-redis"

user_ids = [
aws_elasticache_user.cache_default_user.id,
aws_elasticache_user.cache_iam_user.id
]

lifecycle {
ignore_changes = [user_ids]
}
}

resource "aws_elasticache_user" "cache_default_user" {
user_id = "${terraform.workspace}-${var.app}-default-disabled"
user_name = "default"
access_string = "off ~keys* -@all +get"
authentication_mode {
type = "no-password-required"
}
lifecycle {
ignore_changes = [authentication_mode]
}
engine = "REDIS"
}

resource "aws_elasticache_user" "cache_iam_user" {
user_id = "${terraform.workspace}-${var.app}-iam-user"
user_name = "${terraform.workspace}-${var.app}-iam-user"
access_string = "on ~* +@all"
authentication_mode {
type = "iam"
}
engine = "REDIS"
}

resource "aws_security_group" "cache_security_group" {

name = "${terraform.workspace}-${var.app}-cache-security-group"
description = "Security group for VPC access to redis"
vpc_id = aws_vpc.vpc.id
ingress {
cidr_blocks = [aws_vpc.vpc.cidr_block]
description = "Redis"
from_port = 6379
to_port = 6379
protocol = "tcp"
}
}
Loading
Loading