Skip to content

Commit 91611c6

Browse files
committed
feat: WIP push infra within agent package(s)
Initial draft to push agent infrastructure (ECR repository + image, IAM execution role) within the agent package itself, in preparation for expanding the repo with multiple example agents.
1 parent 9a559b9 commit 91611c6

File tree

5 files changed

+128
-18
lines changed

5 files changed

+128
-18
lines changed

cx-agent-backend/infra/main.tf

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
data "aws_caller_identity" "current" {}
2+
data "aws_region" "current" {}
3+
4+
locals {
5+
image_src_path = "${path.module}/.."
6+
image_src_hash = sha512(
7+
join(
8+
"",
9+
# TODO: Find a way to exclude .venv, dist, and potentially other subfolders:
10+
[for f in fileset(".", "${local.image_src_path}/**") : filesha512(f)]
11+
)
12+
)
13+
14+
image_build_extra_args = "--platform linux/arm64"
15+
image_build_push_cmd = <<-EOT
16+
aws ecr get-login-password | finch login --username AWS \
17+
--password-stdin ${aws_ecr_repository.ecr_repository.repository_url} &&
18+
19+
finch build ${local.image_build_extra_args} \
20+
-t ${aws_ecr_repository.ecr_repository.repository_url}:${var.image_tag} \
21+
${local.image_src_path} &&
22+
23+
finch push ${aws_ecr_repository.ecr_repository.repository_url}:${var.image_tag}
24+
EOT
25+
}
26+
27+
resource "aws_ecr_repository" "ecr_repository" {
28+
name = var.agent_name
29+
}
30+
31+
resource "terraform_data" "ecr_image" {
32+
triggers_replace = [
33+
aws_ecr_repository.ecr_repository.id,
34+
var.force_image_rebuild == true ? timestamp() : local.image_src_hash
35+
]
36+
37+
input = "${aws_ecr_repository.ecr_repository.repository_url}:${var.image_tag}"
38+
39+
provisioner "local-exec" {
40+
command = local.image_build_push_cmd
41+
}
42+
}
43+
44+
resource "aws_iam_role" "execution_role" {
45+
assume_role_policy = jsonencode({
46+
Version = "2012-10-17"
47+
Statement = [
48+
{
49+
Sid = "AssumeRolePolicy"
50+
Effect = "Allow"
51+
Principal = {
52+
Service = "bedrock-agentcore.amazonaws.com"
53+
}
54+
Action = "sts:AssumeRole"
55+
Condition = {
56+
StringEquals = {
57+
"aws:SourceAccount" = data.aws_caller_identity.current.account_id
58+
}
59+
ArnLike = {
60+
"aws:SourceArn" = "arn:aws:bedrock-agentcore:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"
61+
}
62+
}
63+
}
64+
]
65+
})
66+
}

cx-agent-backend/infra/outputs.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
output "ecr_repository_uri" {
2+
description = "URI of the Amazon ECR repository for the agent container image"
3+
value = aws_ecr_repository.ecr_repository.repository_url
4+
}
5+
6+
output "ecr_image_uri" {
7+
description = "URI of the Amazon ECR repository for the agent container image"
8+
value = terraform_data.ecr_image.output
9+
}
10+
11+
output "role_arn" {
12+
description = "ARN of the IAM role for the agent"
13+
value = aws_iam_role.execution_role.arn
14+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
terraform {
2+
required_providers {
3+
aws = {}
4+
}
5+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
variable "agent_name" {
2+
description = "Unique name of the agent"
3+
default = "cx_agent_backend"
4+
type = string
5+
validation {
6+
condition = can(regex("^[a-zA-Z0-9_]+$", var.agent_name))
7+
error_message = "Agent name must contain only letters, numbers, and underscores."
8+
}
9+
}
10+
11+
variable "force_image_rebuild" {
12+
description = "Set true to force rebuild & push of image to ECR even if source appears unchanged"
13+
default = false
14+
type = bool
15+
}
16+
17+
variable "image_tag" {
18+
description = "Tag to apply to the pushed container image in Amazon ECR"
19+
default = "latest"
20+
type = string
21+
}

infra/main.tf

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
# Bedrock Agent Role
22
module "bedrock_role" {
3-
source = "./modules/agentcore-iam-role"
4-
role_name = var.bedrock_role_name
3+
source = "./modules/agentcore-iam-role"
4+
role_name = var.bedrock_role_name
55
knowledge_base_id = module.kb_stack.knowledge_base_id
6-
guardrail_id = module.guardrail.guardrail_id
6+
guardrail_id = module.guardrail.guardrail_id
7+
}
8+
9+
# Example Agent
10+
module "cx_agent_demo" {
11+
source = "../cx-agent-backend/infra"
712
}
813

914
# Knowledge Base Stack
1015
module "kb_stack" {
11-
source = "./modules/kb-stack"
12-
name = var.kb_stack_name
13-
bucket_name = var.kb_bucket_name
16+
source = "./modules/kb-stack"
17+
name = var.kb_stack_name
1418
kb_model_arn = var.kb_model_arn
1519
}
1620

1721
# Guardrail Module
1822
module "guardrail" {
1923
source = "./modules/bedrock-guardrails"
20-
guardrail_name = "agentic-ai-guardrail"
21-
blocked_input_messaging = "Your input contains content that violates our policy."
24+
guardrail_name = "agentic-ai-guardrail"
25+
blocked_input_messaging = "Your input contains content that violates our policy."
2226
blocked_outputs_messaging = "The response was blocked due to policy violations."
23-
description = "Guardrail for agentic AI foundation"
27+
description = "Guardrail for agentic AI foundation"
2428
}
2529

2630
# Cognito Module
@@ -47,19 +51,19 @@ module "parameters" {
4751
# Secrets Module (depends on Cognito for client secret)
4852
module "secrets" {
4953
source = "./modules/secrets"
50-
54+
5155
cognito_client_secret = module.cognito.client_secret
52-
56+
5357
# Placeholder values - replace with actual values
54-
zendesk_domain = var.zendesk_domain
55-
zendesk_email = var.zendesk_email
56-
zendesk_api_token = var.zendesk_api_token
57-
langfuse_host = var.langfuse_host
58+
zendesk_domain = var.zendesk_domain
59+
zendesk_email = var.zendesk_email
60+
zendesk_api_token = var.zendesk_api_token
61+
langfuse_host = var.langfuse_host
5862
langfuse_public_key = var.langfuse_public_key
5963
langfuse_secret_key = var.langfuse_secret_key
60-
gateway_url = var.gateway_url
61-
gateway_api_key = var.gateway_api_key
62-
tavily_api_key = var.tavily_api_key
64+
gateway_url = var.gateway_url
65+
gateway_api_key = var.gateway_api_key
66+
tavily_api_key = var.tavily_api_key
6367

6468
depends_on = [module.cognito]
6569
}

0 commit comments

Comments
 (0)