Skip to content

Commit

Permalink
chore: Add tx bot to terraform (#7609)
Browse files Browse the repository at this point in the history
Adds a job to devnet-deploys to deploy (but not start) the bot using
terraform. The bot tf template is the same as the pxe's, but without a
volume, since the bot does not require storage. The bot uses the remote
deployed pxe instead of running its own, and requires two new secrets
(`BOT_API_KEY` and `BOT_PRIVATE_KEY`) to be defined.
  • Loading branch information
spalladino authored Jul 25, 2024
1 parent ac206a6 commit 6caa914
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 2 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/devnet-deploys.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ env:
TF_VAR_FORK_MNEMONIC: ${{ secrets.FORK_MNEMONIC }}
TF_VAR_INFURA_API_KEY: ${{ secrets.INFURA_API_KEY }}
TF_VAR_FAUCET_ACCOUNT_INDEX: 5
TF_VAR_BOT_API_KEY: ${{ secrets.BOT_API_KEY }}
TF_VAR_BOT_PRIVATE_KEY: ${{ secrets.BOT_PRIVATE_KEY }}
CONTRACT_S3_BUCKET: s3://aztec-devnet-deployments

jobs:
Expand Down Expand Up @@ -258,3 +260,29 @@ jobs:
run: |
terraform init -input=false -backend-config="key=${{ env.DEPLOY_TAG }}/aztec-faucet"
terraform apply -input=false -auto-approve
deploy-bot:
runs-on: ubuntu-latest
needs: [terraform_deploy, bootstrap]
steps:
- uses: actions/checkout@v4
with:
ref: "${{ env.GIT_COMMIT }}"
fetch-depth: 0
- uses: ./.github/ci-setup-action
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.7.5

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-2

- name: Deploy transactions bot
working-directory: ./yarn-project/aztec/terraform/bot
run: |
terraform init -input=false -backend-config="key=${{ env.DEPLOY_TAG }}/bot"
terraform apply -input=false -auto-approve
7 changes: 5 additions & 2 deletions yarn-project/aztec/src/cli/cmds/start_bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function startBot(
return services;
}

export async function addBot(
export function addBot(
options: any,
services: ServerList,
signalHandlers: (() => Promise<void>)[],
Expand All @@ -37,7 +37,10 @@ export async function addBot(

const botRunner = new BotRunner(config, { pxe: deps.pxe });
const botServer = createBotRunnerRpcServer(botRunner);
await botRunner.start();
if (!config.noStart) {
void botRunner.start(); // Do not block since bot setup takes time
}
services.push({ bot: botServer });
signalHandlers.push(botRunner.stop);
return Promise.resolve();
}
186 changes: 186 additions & 0 deletions yarn-project/aztec/terraform/bot/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
terraform {
backend "s3" {
bucket = "aztec-terraform"
region = "eu-west-2"
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.74.2"
}
}
}

# Define provider and region
provider "aws" {
region = "eu-west-2"
}

data "terraform_remote_state" "aztec2_iac" {
backend = "s3"
config = {
bucket = "aztec-terraform"
key = "aztec2/iac"
region = "eu-west-2"
}
}

data "terraform_remote_state" "setup_iac" {
backend = "s3"
config = {
bucket = "aztec-terraform"
key = "setup/setup-iac"
region = "eu-west-2"
}
}

resource "aws_cloudwatch_log_group" "aztec-bot-log-group" {
name = "/fargate/service/${var.DEPLOY_TAG}/aztec-bot"
retention_in_days = 14
}

resource "aws_service_discovery_service" "aztec-bot" {
name = "${var.DEPLOY_TAG}-aztec-bot"

health_check_custom_config {
failure_threshold = 1
}

dns_config {
namespace_id = data.terraform_remote_state.setup_iac.outputs.local_service_discovery_id

dns_records {
ttl = 60
type = "A"
}

dns_records {
ttl = 60
type = "SRV"
}

routing_policy = "MULTIVALUE"
}

# Terraform just fails if this resource changes and you have registered instances.
provisioner "local-exec" {
when = destroy
command = "${path.module}/../servicediscovery-drain.sh ${self.id}"
}
}

locals {
api_prefix = "/${var.DEPLOY_TAG}/aztec-bot/${var.BOT_API_KEY}"
}

resource "aws_ecs_task_definition" "aztec-bot" {
family = "${var.DEPLOY_TAG}-aztec-bot"
network_mode = "awsvpc"
cpu = 2048
memory = 4096
requires_compatibilities = ["FARGATE"]
execution_role_arn = data.terraform_remote_state.setup_iac.outputs.ecs_task_execution_role_arn
task_role_arn = data.terraform_remote_state.aztec2_iac.outputs.cloudwatch_logging_ecs_role_arn

container_definitions = jsonencode([
{
name = "${var.DEPLOY_TAG}-aztec-bot"
image = "${var.DOCKERHUB_ACCOUNT}/aztec:${var.DEPLOY_TAG}"
command = ["start", "--bot"]
essential = true
portMappings = [
{
containerPort = 80
hostPort = 80
}
]
environment = [
{ name = "BOT_PRIVATE_KEY", value = var.BOT_PRIVATE_KEY },
{ name = "BOT_NO_START", value = "true" },
{ name = "BOT_PXE_URL", value = "http://${var.DEPLOY_TAG}-aztec-pxe-1.local/${var.DEPLOY_TAG}/aztec-pxe-1/${var.API_KEY}" },
{ name = "BOT_TX_INTERVAL_SECONDS", value = 300 },
{ name = "AZTEC_PORT", value = "80" },
{ name = "API_PREFIX", value = local.api_prefix },
]
logConfiguration = {
logDriver = "awslogs"
options = {
"awslogs-group" = aws_cloudwatch_log_group.aztec-bot-log-group.name
"awslogs-region" = "eu-west-2"
"awslogs-stream-prefix" = "ecs"
}
}
}
])
}

resource "aws_ecs_service" "aztec-bot" {
name = "${var.DEPLOY_TAG}-aztec-bot"
cluster = data.terraform_remote_state.setup_iac.outputs.ecs_cluster_id
launch_type = "FARGATE"
desired_count = 1
deployment_maximum_percent = 100
deployment_minimum_healthy_percent = 0
platform_version = "1.4.0"
force_new_deployment = true

network_configuration {
subnets = [
data.terraform_remote_state.setup_iac.outputs.subnet_az1_private_id,
data.terraform_remote_state.setup_iac.outputs.subnet_az2_private_id
]
security_groups = [data.terraform_remote_state.setup_iac.outputs.security_group_private_id]
}

load_balancer {
target_group_arn = aws_alb_target_group.bot_http.arn
container_name = "${var.DEPLOY_TAG}-aztec-bot"
container_port = 80
}

service_registries {
registry_arn = aws_service_discovery_service.aztec-bot.arn
container_name = "${var.DEPLOY_TAG}-aztec-bot"
container_port = 80
}

task_definition = aws_ecs_task_definition.aztec-bot.family
}

resource "aws_alb_target_group" "bot_http" {
name = "${var.DEPLOY_TAG}-bot-http"
port = 80
protocol = "HTTP"
target_type = "ip"
vpc_id = data.terraform_remote_state.setup_iac.outputs.vpc_id
deregistration_delay = 5

health_check {
path = "${local.api_prefix}/status"
matcher = 200
interval = 10
healthy_threshold = 2
unhealthy_threshold = 5
timeout = 5
}

tags = {
name = "${var.DEPLOY_TAG}-bot-http"
}
}

resource "aws_lb_listener_rule" "bot_api" {
listener_arn = data.terraform_remote_state.aztec2_iac.outputs.alb_listener_arn
priority = 700

action {
type = "forward"
target_group_arn = aws_alb_target_group.bot_http.arn
}

condition {
path_pattern {
values = ["${local.api_prefix}*"]
}
}
}
19 changes: 19 additions & 0 deletions yarn-project/aztec/terraform/bot/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
variable "DEPLOY_TAG" {
type = string
}

variable "DOCKERHUB_ACCOUNT" {
type = string
}

variable "API_KEY" {
type = string
}

variable "BOT_API_KEY" {
type = string
}

variable "BOT_PRIVATE_KEY" {
type = string
}
5 changes: 5 additions & 0 deletions yarn-project/bot/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export type BotConfig = {
publicTransfersPerTx: number;
/** How to handle fee payments. */
feePaymentMethod: 'native' | 'none';
/** True to not automatically setup or start the bot on initialization. */
noStart: boolean;
};

export function getBotConfigFromEnv(): BotConfig {
Expand All @@ -29,6 +31,7 @@ export function getBotConfigFromEnv(): BotConfig {
BOT_TX_INTERVAL_SECONDS,
BOT_PRIVATE_TRANSFERS_PER_TX,
BOT_PUBLIC_TRANSFERS_PER_TX,
BOT_NO_START,
} = process.env;
if (BOT_FEE_PAYMENT_METHOD && !['native', 'none'].includes(BOT_FEE_PAYMENT_METHOD)) {
throw new Error(`Invalid bot fee payment method: ${BOT_FEE_PAYMENT_METHOD}`);
Expand All @@ -45,6 +48,7 @@ export function getBotConfigFromEnv(): BotConfig {
privateTransfersPerTx: BOT_PRIVATE_TRANSFERS_PER_TX ? parseInt(BOT_PRIVATE_TRANSFERS_PER_TX) : undefined,
publicTransfersPerTx: BOT_PUBLIC_TRANSFERS_PER_TX ? parseInt(BOT_PUBLIC_TRANSFERS_PER_TX) : undefined,
feePaymentMethod: BOT_FEE_PAYMENT_METHOD ? (BOT_FEE_PAYMENT_METHOD as 'native' | 'none') : undefined,
noStart: BOT_NO_START ? ['1', 'true'].includes(BOT_NO_START) : undefined,
});
}

Expand All @@ -58,6 +62,7 @@ export function getBotDefaultConfig(overrides: Partial<BotConfig> = {}): BotConf
privateTransfersPerTx: 1,
publicTransfersPerTx: 1,
feePaymentMethod: 'none',
noStart: false,
...compact(overrides),
};
}

0 comments on commit 6caa914

Please sign in to comment.