Последняя проверка: май 2026 г.
Разверните сервисы AWS для экзамена AIP-C01 с помощью чистого Terraform: пошаговое руководство с привязкой каждого блока к разделам экзамена. Код также совместим с OpenTofu.
К концу этой лабораторной работы вы настроите с помощью чистого Terraform производственный агент Bedrock — бакет S3 для любых исходных данных, роль IAM с минимальными привилегиями, которую принимает агент, надежную защитную систему Bedrock Guardrail (фильтры по содержанию + PII + запрещенные темы), сам агент Bedrock и группу действий Action Group, которая позволяет агенту вызывать функцию Lambda в качестве инструмента. Это эталонная архитектура AIP-C01 для генеративного ИИ, вызывающего инструменты: модель с защитными ограждениями, ограниченными разрешениями и вызываемой поверхностью расширения.
Каждый ресурс — это чистый Terraform. Вставьте фрагменты в один файл main.tf, запустите terraform init, а затем terraform apply пошагово.
>= 1.5 или OpenTofu >= 1.6.us-east-1 (там поддержка Bedrock Agents наиболее полная).anthropic.claude-3-haiku-20240307-v1:0 (агент в шаге 4 ссылается на нее). Доступ к моделям — это переключатель на уровне учетной записи, находящийся вне инфраструктуры как кода.aws_bedrockagent_* требуют провайдера AWS ~> 5.60, и сервис Bedrock Agent должен быть общедоступен (GA) в вашем регионе. Проверьте в консоли AWS, работает ли aws bedrock-agent list-agents.Плата за простой минимальна; счет зависит от использования:
Ловушка затрат, которую специально проверяет AIP-C01: Базы знаний Bedrock Knowledge Bases требуют коллекцию OpenSearch Serverless, которая тарифицируется от $350/месяц за простой. Лабораторная работа намеренно НЕ создает базу знаний Knowledge Base — шаблон Action Group в шаге 5 демонстрирует более распространенную форму агента, вызывающего инструменты, без ловушки OpenSearch. Если вы хотите изучить базы знаний, сначала изучите их концептуально; создавайте коллекцию OSS только тогда, когда будете готовы ее реально использовать.
Стандартное начало. us-east-1 для максимально широкой доступности функций Bedrock + Bedrock Agent. Фиксация версии провайдера не подлежит обсуждению: ресурсы aws_bedrockagent_* требуют ~> 5.60 или более позднюю версию.
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" {}Большинство производственных агентов Bedrock в конечном итоге читают что-то из S3 — исходные документы базы знаний, определения инструментов JSON, шаблоны ответов. Мы заранее выделяем бакет, чтобы не пришлось настраивать разрешения позже. Шифрование + настройки блокировки публичного доступа по умолчанию — это область AIP-C01 «Интеграция базовых моделей, управление данными и соответствие требованиям» в действии.
Экзамен AIP-C01 проверяет один конкретный шаблон соответствия, связанный с этим бакетом: шифрование на стороне клиента с ключом, управляемым приложением, является правильным ответом, когда регулирование гласит: "AWS никогда не должна иметь незашифрованные данные". Для всего остального достаточно SSE-S3 (что мы здесь и делаем).
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"
}
}
}Область AIP-C01 «Безопасность, защита и управление ИИ» (20% экзамена) гораздо глубже, чем версия AIF-C01. Экзамен проверяет многоуровневую композицию защитного ограждения: контентные фильтры для вредоносных категорий с высокой степенью строгости, политики конфиденциальной информации для PII (с BLOCK, а не в стиле AIF ANONYMIZE — производственным агентам обычно нужны жесткие блокировки) и политики тем для запрещенных тем, специфичных для приложений.
Мы настраиваем все три. Запрещенная тема "FinancialAdvice" в политике — это распространенное производственное защитное ограждение для нефинансовых чат-ботов; даже Claude 3 иногда начинает давать советы по акциям, если вы не скажете защитному ограждению блокировать отклонение от темы. AIP-C01 проверяет именно этот шаблон композиции в сценарных вопросах, где запрос безобиден, но ответ может выйти за рамки политики.
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"
}
}
}Агент связывает базовую модель, системный промпт и (в шаге 5) одну или несколько групп действий, которые расширяют его возможности. Роль IAM, которую мы прикрепляем, является ролью выполнения агента — это то, что агент использует для вызова моделей, извлечения данных из баз знаний и вызова функций Lambda групп действий. Область AIP-C01 «Внедрение и интеграция» проверяет именно эту форму роли/доверия: bedrock.amazonaws.com в качестве субъекта, ограниченные разрешения на bedrock:InvokeModel для определенных ARN моделей и lambda:InvokeFunction для определенных ARN функций.
Поле instruction агента — это системный промпт: короткий, ориентированный на действие, называющий назначение агента. Вопросы AIP-C01 об инженерии промптов на уровне агента проверяют именно это: инструкция — это постоянная личность; сообщение пользователя меняется каждый раз.
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
}
}Группы действий (Action Groups) — это способ, которым агенты Bedrock обращаются к вашему коду. Шаблон такой: определите схему API (что принимает и возвращает инструмент), укажите на функцию Lambda, которая реализует действия, а Bedrock позаботится об остальном — когда модель решит, что ей нужен инструмент, она вызовет вашу Lambda со структурированными аргументами и вернет ответ в разговор.
Мы определяем минимальное действие get_current_time со схемой OpenAPI 3.0, которую ожидает Bedrock. Реализация Lambda намеренно крошечная — экзамен проверяет именно форму интеграции (вызывающая функцию Lambda + схема OpenAPI + разрешение на вызов Bedrock), а не внутреннюю логику функции.
Ресурс aws_lambda_permission — это каноническая «заковырка» AIP-C01: без него вызов Lambda агентом получит AccessDenied даже если все остальные части подключены правильно. Bedrock Agent → Lambda — это шаблон вызова внешней службы; политика ресурсов функции должна явно разрешать bedrock.amazonaws.com.
С внедрением групп действий полная форма агента завершена: модель + системный промпт + защитное ограждение + расширяемость вызовом инструментов, все под одной ограниченной идентификацией IAM. Каждый дополнительный шаблон AIP-C01 (извлечение из базы знаний, агенты с несколькими действиями, сотрудничество агентов через агентов-супервайзеров) расширяет эту базу.
# ── 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 удаляет все в этой лабораторной работе, с учетом порядка:
force_destroy = false. Если вы загрузили какие-либо справочные данные, очистите его (aws s3 rm s3://<bucket> --recursive) перед удалением.AIP-C01 охватывает производственные GenAI поверхности, которые эта лабораторная работа не может вместить — Bedrock Knowledge Bases (требуют OpenSearch Serverless = от $350+/месяц за простой, намеренно пропущено согласно примечанию о стоимости), Bedrock Agent Aliases для переключения трафика и управления версиями, многоагентное сотрудничество (агенты-супервайзеры, делегирующие задачи специализированным субагентам), память агента для длительного состояния разговора, Bedrock Custom Models (тонкая настройка), Bedrock Provisioned Throughput для высокообъемных производственных развертываний, Amazon Q for Business (нет ресурсов Terraform), SageMaker JumpStart для размещения базовых моделей вне платформы, и стек наблюдаемости Bedrock (логирование вызовов моделей глубже, чем было охвачено AIF-C01).
Мы придерживаемся формы Agent + Action Group + Production Guardrail, потому что это наиболее часто проверяемая на экзамене архитектура производственного GenAI и субстрат, к которому прикрепляются все более продвинутые шаблоны. Базы знаний прикрепляются к этому агенту. Алиасы версионируют этого агента. Многоагентное сотрудничество компонует агентов, подобных этому.
Для охвата вышеуказанных поверхностей концептуальный материал находится в разделах Просмотр, Справочник и Editorial этой страницы сертификации. Естественной последующей лабораторной работой было бы добавление базы знаний Knowledge Base поверх этой базы (стоимость OpenSearch — единственная причина, по которой мы не включаем ее здесь).