Última revisão: maio de 2026
Construa os serviços da AWS do exame AIP-C01 com Terraform puro — um bloco de cada vez, cada um vinculado a um domínio do exame. O mesmo código funciona no OpenTofu.
Ao final deste laboratório, você terá provisionado, com Terraform simples, um Agente Bedrock com formato de produção — um bucket S3 para quaisquer dados de origem, um perfil IAM de privilégio mínimo que o agente assume, um Guardrail Bedrock de força de produção (filtros de conteúdo + PII + tópicos negados), o próprio Agente Bedrock e um Grupo de Ação que permite ao agente invocar uma função Lambda como ferramenta. Esta é a arquitetura de referência AIP-C01 para IA generativa que invoca ferramentas: um modelo com grades de segurança, permissões delimitadas e uma superfície de extensão invocável.
Cada recurso é Terraform puro. Adicione os trechos em um único main.tf, execute terraform init e depois terraform apply passo a passo.
>= 1.5 ou OpenTofu >= 1.6.us-east-1 (o suporte para Agentes Bedrock é mais amplo lá).anthropic.claude-3-haiku-20240307-v1:0 no mínimo (o agente na Etapa 4 o referencia). O acesso ao modelo é uma opção de nível de conta fora da infraestrutura como código.aws_bedrockagent_* exigem o provedor AWS ~> 5.60 e o serviço Agente Bedrock deve estar GA em sua região. Verifique o console AWS se aws bedrock-agent list-agents funciona.A cobrança de inatividade é mínima; a fatura escala com o uso:
A armadilha de custo que o AIP-C01 testa especificamente: as Bases de Conhecimento do Bedrock exigem uma coleção OpenSearch Serverless que cobra um mínimo de ~$350/mês de inatividade. O laboratório deliberadamente NÃO provisiona uma Base de Conhecimento — o padrão de Grupo de Ação na Etapa 5 demonstra a forma mais comum de agente que invoca ferramentas, sem a armadilha do OpenSearch. Se você deseja estudar Bases de Conhecimento, faça-o conceitualmente primeiro; provisione a coleção OSS apenas quando estiver pronto para realmente usá-la.
Abertura padrão. us-east-1 para a mais ampla disponibilidade de recursos do Bedrock + Agente Bedrock. A fixação da versão do provedor não é negociável: os recursos aws_bedrockagent_* exigem ~> 5.60 ou posterior.
terraform {
required_version = ">= 1.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.60"
}
archive = {
source = "hashicorp/archive"
version = "~> 2.4"
}
}
}
provider "aws" {
region = "us-east-1"
default_tags {
tags = {
Project = "certlabpro-aip-c01"
ManagedBy = "terraform"
}
}
}
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}A maioria dos Agentes Bedrock em produção acaba lendo algo do S3 — documentos de origem de bases de conhecimento, definições de ferramentas JSON, modelos de resposta. Provisionamos um bucket antecipadamente para não ter que configurar permissões posteriormente. A criptografia + os padrões de bloqueio de acesso público são o domínio Integração de Modelo de Fundação, Gerenciamento de Dados e Conformidade do AIP-C01 em ação.
O exame AIP-C01 testa um padrão de conformidade específico em torno deste bucket: criptografia do lado do cliente com uma chave que a aplicação controla é a resposta correta quando a regulamentação diz "A AWS nunca deve ter os dados não criptografados". Para todo o resto, SSE-S3 (o que fazemos aqui) é suficiente.
resource "aws_s3_bucket" "agent_data" {
bucket_prefix = "certlabpro-aip-c01-"
}
resource "aws_s3_bucket_public_access_block" "agent_data" {
bucket = aws_s3_bucket.agent_data.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_server_side_encryption_configuration" "agent_data" {
bucket = aws_s3_bucket.agent_data.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}O domínio Segurança, Proteção e Governança de IA do AIP-C01 (20% do exame) aprofunda-se muito mais do que a versão do AIF-C01. O exame testa a composição de guardrails em múltiplas camadas: filtros de conteúdo para categorias prejudiciais em alta intensidade, políticas de informações sensíveis para PII (com BLOCK em vez do estilo AIF ANONYMIZE — agentes de produção geralmente precisam de bloqueios rígidos) e políticas de tópicos para temas proibidos específicos da aplicação.
Configuramos todos os três. O tópico negado "FinancialAdvice" na política é um guardrail de produção comum para chatbots não financeiros — até mesmo o Claude 3 pode ocasionalmente dar dicas de ações, a menos que você diga ao guardrail para bloquear o desvio de tópico. O AIP-C01 testa exatamente esse padrão de composição em questões de cenário onde o prompt é benigno, mas a resposta pode desviar da política.
resource "aws_bedrock_guardrail" "production" {
name = "certlabpro-aip-c01-production"
description = "Production-grade safety rail for the AIP-C01 lab agent."
blocked_input_messaging = "I can't help with that request."
blocked_outputs_messaging = "I can't share that response."
content_policy_config {
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "HATE"
}
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "VIOLENCE"
}
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "SEXUAL"
}
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "INSULTS"
}
filters_config {
input_strength = "HIGH"
output_strength = "HIGH"
type = "MISCONDUCT"
}
}
sensitive_information_policy_config {
pii_entities_config {
action = "BLOCK"
type = "EMAIL"
}
pii_entities_config {
action = "BLOCK"
type = "PHONE"
}
pii_entities_config {
action = "BLOCK"
type = "US_SOCIAL_SECURITY_NUMBER"
}
pii_entities_config {
action = "BLOCK"
type = "CREDIT_DEBIT_CARD_NUMBER"
}
}
topic_policy_config {
topics_config {
name = "FinancialAdvice"
definition = "Specific recommendations to buy, sell, or hold financial instruments."
examples = ["Should I buy NVDA?", "Is now a good time to sell my Bitcoin?"]
type = "DENY"
}
}
}O agente conecta um modelo de base, um prompt de sistema e (na Etapa 5) um ou mais grupos de ação que estendem suas capacidades. O perfil IAM que anexamos é o perfil de execução do agente — é o que o agente usa para invocar modelos, recuperar de bases de conhecimento e chamar Lambdas de grupos de ação. O domínio Implementação e Integração do AIP-C01 testa exatamente essa forma de perfil/confiança: bedrock.amazonaws.com como principal, permissões com escopo para bedrock:InvokeModel em ARNs de modelos específicos e lambda:InvokeFunction em ARNs de funções específicas.
O campo instruction do agente é o prompt de sistema — curto, orientado à ação, nomeando o propósito do agente. As perguntas do AIP-C01 sobre engenharia de prompt no nível do agente testam exatamente isso: a instrução é a personalidade persistente; a mensagem do usuário muda a cada turno.
resource "aws_iam_role" "agent" {
name = "certlabpro-aip-c01-agent"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "bedrock.amazonaws.com" }
Action = "sts:AssumeRole"
Condition = {
StringEquals = {
"aws:SourceAccount" = data.aws_caller_identity.current.account_id
}
}
}]
})
}
resource "aws_iam_role_policy" "agent_invoke_model" {
name = "invoke-foundation-model"
role = aws_iam_role.agent.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"]
Resource = "arn:aws:bedrock:${data.aws_region.current.name}::foundation-model/anthropic.claude-3-haiku-20240307-v1:0"
}]
})
}
resource "aws_bedrockagent_agent" "main" {
agent_name = "certlabpro-aip-c01-agent"
agent_resource_role_arn = aws_iam_role.agent.arn
foundation_model = "anthropic.claude-3-haiku-20240307-v1:0"
instruction = "You are a helpful assistant for the certlabpro AIP-C01 lab. Answer concisely. When the user asks about the current time, use the get_current_time tool."
idle_session_ttl_in_seconds = 600
# Attach the guardrail from Step 3. Bedrock evaluates inputs and outputs
# against the guardrail policy on every model call.
guardrail_configuration {
guardrail_identifier = aws_bedrock_guardrail.production.guardrail_id
guardrail_version = aws_bedrock_guardrail.production.version
}
}Grupos de Ação são como os Agentes Bedrock invocam seu código. O padrão: defina o esquema da API (o que a ferramenta aceita e retorna), aponte para uma Lambda que implementa as ações, e o Bedrock lida com o resto — quando o modelo decide que precisa da ferramenta, ele chama sua Lambda com argumentos estruturados e insere a resposta de volta na conversa.
Definimos uma ação get_current_time mínima com o esquema OpenAPI 3.0 que o Bedrock espera. A implementação da Lambda é intencionalmente pequena — o que o exame testa é a forma da integração (Lambda que invoca funções + esquema OpenAPI + permissão de invocação do Bedrock), não a lógica interna da função.
O recurso aws_lambda_permission é a pegadinha canônica do AIP-C01: sem ele, a invocação da Lambda pelo agente recebe AccessDenied, mesmo que todas as outras partes estejam corretamente conectadas. Agente Bedrock → Lambda é um padrão de invocação de serviço externo; a política de recurso da função precisa permitir bedrock.amazonaws.com explicitamente.
Com os Grupos de Ação em vigor, a forma completa do agente está concluída: modelo + prompt de sistema + guardrail de segurança + extensibilidade de invocação de ferramentas, tudo sob uma identidade IAM com escopo definido. Cada padrão adicional do AIP-C01 (recuperação de Base de Conhecimento, agentes multi-ação, colaboração entre agentes via agentes supervisores) estende essa base.
# ── Lambda tool ───────────────────────────────────────────────
data "archive_file" "tool" {
type = "zip"
output_path = "${path.module}/build/tool.zip"
source {
filename = "index.py"
content = <<-EOT
import json
from datetime import datetime, timezone
def handler(event, context):
# Bedrock Agent passes the parsed args under `requestBody` / `parameters`.
# For a simple no-arg tool, just return the current time.
now_iso = datetime.now(timezone.utc).isoformat()
return {
"messageVersion": "1.0",
"response": {
"actionGroup": event.get("actionGroup", ""),
"apiPath": event.get("apiPath", "/"),
"httpMethod": event.get("httpMethod", "GET"),
"httpStatusCode": 200,
"responseBody": {"application/json": {"body": json.dumps({"current_time_utc": now_iso})}},
},
}
EOT
}
}
resource "aws_iam_role" "tool_lambda" {
name = "certlabpro-aip-c01-tool"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
resource "aws_iam_role_policy_attachment" "tool_logs" {
role = aws_iam_role.tool_lambda.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
resource "aws_lambda_function" "tool" {
function_name = "certlabpro-aip-c01-tool"
role = aws_iam_role.tool_lambda.arn
runtime = "python3.12"
handler = "index.handler"
filename = data.archive_file.tool.output_path
source_code_hash = data.archive_file.tool.output_base64sha256
timeout = 10
}
resource "aws_lambda_permission" "agent_invoke_tool" {
statement_id = "AllowBedrockAgentInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.tool.function_name
principal = "bedrock.amazonaws.com"
source_arn = aws_bedrockagent_agent.main.agent_arn
}
# Also let the agent invoke the lambda from its execution role.
resource "aws_iam_role_policy" "agent_invoke_lambda" {
name = "invoke-tool"
role = aws_iam_role.agent.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = "lambda:InvokeFunction"
Resource = aws_lambda_function.tool.arn
}]
})
}
# ── Action Group ──────────────────────────────────────────────
resource "aws_bedrockagent_agent_action_group" "time" {
action_group_name = "time-tools"
agent_id = aws_bedrockagent_agent.main.agent_id
agent_version = "DRAFT"
description = "Time-related tool calls for the agent."
skip_resource_in_use_check = false
action_group_executor {
lambda = aws_lambda_function.tool.arn
}
api_schema {
payload = jsonencode({
openapi = "3.0.0"
info = { title = "Time tools", version = "1.0.0" }
paths = {
"/get_current_time" = {
get = {
operationId = "get_current_time"
description = "Returns the current UTC time as an ISO-8601 string."
responses = {
"200" = {
description = "Current UTC time"
content = {
"application/json" = {
schema = {
type = "object"
properties = {
current_time_utc = { type = "string", format = "date-time" }
}
}
}
}
}
}
}
}
}
})
}
}terraform destroy derruba tudo neste laboratório, com atenção à ordem:
force_destroy = false. Se você carregou quaisquer dados de referência, esvazie-o (aws s3 rm s3://<bucket> --recursive) antes de destruir.O AIP-C01 abrange superfícies de GenAI de produção que este laboratório não pode incluir — Bases de Conhecimento do Bedrock (exigem OpenSearch Serverless = $350+/mês ocioso, deliberadamente omitido conforme a nota de custo), Aliases de Agente Bedrock para redirecionamento de tráfego e gerenciamento de versão, colaboração multiagente (agentes supervisores que delegam a subagentes especialistas), memória de agente para estado conversacional de longa duração, Modelos Personalizados do Bedrock (fine-tuning), Capacidade de Processamento Provisionada do Bedrock para implantações de produção de alto volume, Amazon Q para Negócios (sem recursos Terraform), SageMaker JumpStart para hospedagem de modelos de base fora da plataforma, e a pilha de observabilidade do Bedrock (registro de invocação de modelo mais profundo do que o coberto pelo AIF-C01).
Nós nos concentramos na forma Agente + Grupo de Ação + Guardrail de Produção porque é a arquitetura de GenAI de produção mais testada no exame e o substrato ao qual todos os padrões mais avançados se anexam. Bases de Conhecimento se anexam a este agente. Aliases versionam este agente. A colaboração multiagente compõe agentes como este.
Para cobertura das superfícies acima, as seções Navegar, Guia e Editorial desta página de certificação possuem o material conceitual. Um laboratório de acompanhamento natural adicionaria uma Base de Conhecimento em cima desta base (o custo do OpenSearch é a única razão pela qual não a incluímos aqui).