ããã«ã¡ã¯ãã¨ããµã¤ãæ ªå¼ä¼ç¤¾ã®å¹³ç³ã§ãã
ã¨ããµã¤ããã¼ã«ãã£ã³ã°ã¹ Advent Calendar 2024ã®ã·ãªã¼ãº2, 19æ¥ç®ãæ å½ãããã¾ãã
ä»åã¯AWSä¸ã®ECSã³ã³ããã¨Bedrockã®éã®PrivateLinkã確ç«ããæ¹æ³ããç´¹ä»ãã¾ãã
AWSãªã½ã¼ã¹ã®ä½æã«ã¯Terraformã使ãã¾ãã
ã¯ããã«
Amazon Bedrockã¨ã¯
Amazon Bedrockã¯ãAWSä¸ã§çæAIãå©ç¨ã§ããããã«ãããã«ããã¼ã¸ããµã¼ãã¹ã§ãã
æ¢åã®ã¢ãã«ã容æã«å©ç¨ãããã¨ãã§ãã¾ãããç¨éããã¼ã¿ã«åããã¦ã«ã¹ã¿ãã¤ãºãããã¨ãå¯è½ã§ãã
PrivateLinkã¨ã¯
Amazon Bedrockã¯VPCä¸ã«ãªããECSã³ã³ããç°å¢ã§åä½ãã¦ããã¢ããªã±ã¼ã·ã§ã³ããBedrcokãå©ç¨ããéã«ã¯NAT Gatewayãå©ç¨ãããªã©ãã¦ã¤ã³ã¿ã¼ããããçµç±ããå¿
è¦ãããã¾ãã
ããããã¤ã³ã¿ã¼ããããçµç±ããã¨ã»ãã¥ãªãã£ã®åé¡ãçãã¾ãã
PrivateLinkã¯å©ç¨ããAWSãµã¼ãã¹ãVPCä¸ã«ãããã®ããã«æ¥ç¶ããããã®æ¹æ³ã§ãã¤ã³ã¿ã¼ããããçµç±ããªããã©ã¤ãã¼ããªæ¥ç¶ãå¯è½ã«ãªãã¾ãã
PrivateLinkã¯VPCã«ã¢ã¿ããããVPCã¨ã³ããã¤ã³ãã¨ããã³ã³ãã¼ãã³ãã¨æ¥ç¶å ã®AWSãµã¼ãã¹ãçµã³ã¤ãããã¨ã§æ§ç¯ãã¾ãã
ç°å¢
Terraform 1.10.3ã§åä½ç¢ºèªããã¦ãã¾ãã
åææ¡ä»¶
AWSã¢ã«ã¦ã³ãã®ä½æãTerraformã®ç°å¢æ§ç¯ãECSã³ã³ããã®ãããã¤ãBedrockã®ã¢ãã«ã¸ã®ã¢ã¯ã»ã¹è¨±å¯ã¯å®äºãã¦ãããã¨ãåæã¨ãã¦ãã¾ãã
å®è£
Security Groupã¨IAMããªã·ã¼ãä½æãã
ã¾ãã¯ãVPC ã¨ã³ããã¤ã³ãã«ã¢ã¿ããããSecurity Groupãä½æãã¾ãã
./vpc_endpoint/bedrock/main.tf
variable "vpc" { type = object({ vpc_id = string private_subnet_ids = list(string) }) } variable "trusted_security_group_id" { type = string } module "security_group" { source = "terraform-aws-modules/security-group/aws" version = "5.1.0" name = "bedrock-vpce-sg" description = "Security group for bedrock-vpce" vpc_id = var.vpc.vpc_id ingress_with_source_security_group_id = [ { from_port = 443 to_port = 443 protocol = "tcp" source_security_group_id = var.trusted_security_group_id } ] }
è¨å®ããSecurity Groupããã®TCPãããã³ã«ã«ãã443ãã¼ãã¸ã®éä¿¡ã®ã¿è¨±å¯ãã¾ãã
å¤æ°trusted_security_group_id
ã«ã¯ãECSã«ã¢ã¿ããããSecurity Groupã®IDã渡ãã¾ãã
次ã«ãVPCã¨ã³ããã¤ã³ãã«ã¢ã¿ããããããªã·ã¼ããã¥ã¡ã³ããä½æãã¾ãã
./vpc_endpoint/bedrock/main.tf
variable "trusted_role_arns" { type = list(string) } ........ data "aws_iam_policy_document" "bedrock_access_policy" { statement { actions = [ "bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream", ] effect = "Allow" resources = [ "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-*" ] principals { identifiers = var.trusted_role_arns type = "AWS" } } }
ãã®ããªã·ã¼ããã¥ã¡ã³ãã§ã¯ãVPC ã¨ã³ããã¤ã³ãã«Bedrockã®InvokeModel
ã¨InvokeModelWithResponseStream
ã許å¯ãã¾ãã
Bedrockã®ã¢ãã«ã«ã¢ã¯ã»ã¹ãã¦ãçæAIããã®ã¬ã¹ãã³ã¹ãå¾ãããã«ã¯ãã®ããªã·ã¼ãè¨å®ããã°ååã§ãããã
ä»åã¯ãAnthropicã®Claude
ã¨ããã¢ãã«ã«ã¢ã¯ã»ã¹ã§ããããã«ãã¦ãã¾ãã
VPC ã¨ã³ããã¤ã³ããä½æãã
ããã¾ã§ã«ä½æããSecurity Groupãããªã·ã¼ãå©ç¨ãã¦VPCã¨ã³ããã¤ã³ããä½æãã¾ãã
./vpc_endpoint/bedrock/main.tf
resource "aws_vpc_endpoint" "bedrock_vpc_endpoint" { service_name = "com.amazonaws.ap-northeast-1.bedrock-runtime" // â vpc_id = var.vpc.vpc_id vpc_endpoint_type = "Interface" // â¡ subnet_ids = var.vpc.private_subnet_ids policy = data.aws_iam_policy_document.bedrock_claude_policy.json // ⢠security_group_ids = [module.security_group.security_group_id] // ⣠private_dns_enabled = true // ⤠tags = { Name = "bedrock-vpce" } } output "bedrock_vpc_endpoint_id" { value = aws_vpc_endpoint.bedrock_vpc_endpoint.id }
â ã§ã¯ãVPC ã¨ã³ããã¤ã³ãã§VPCã¨PrivateLinkã確ç«ãããµã¼ãã¹ãè¨å®ãã¾ããä»åã¯æ±äº¬ãªã¼ã¸ã§ã³ï¼ap-northeast-1ï¼ã®Bedrockãè¨å®ãã¦ãã¾ãã
â¡ã§ã¯ãVPC ã¨ã³ããã¤ã³ãã®ã¿ã¤ããè¨å®ãã¾ããVPC ã¨ã³ããã¤ã³ãã®ã¿ã¤ãã«ã¯ä¸»ã«Gateway
ã¨Interface
ãããã¾ãã
Gateway ã¨ã³ããã¤ã³ãã¯ç¡æã§å©ç¨ã§ãã¾ãããç¾å¨ã®ã¨ããAmazon S3ã¾ãã¯DynamoDBã¨ã®æ¥ç¶ãããµãã¼ãããã¦ãã¾ããã
ä»åã¯ãBedrockã¨ã®æ¥ç¶ã確ç«ããããInterface ã¨ã³ããã¤ã³ãã«è¨å®ãã¦ãã¾ãã
â¢, â£ã§ã¯ãä¸ã§ä½æããSecurity Groupã¨ããªã·ã¼ãã¢ã¿ãããã¦ãã¾ãã
â¤ã§ã¯ãæå®ããVPCã«ãã©ã¤ãã¼ããã¹ãã¾ã¼ã³ãé¢é£ä»ãããã©ãããè¨å®ãã¾ãã
VPCå
ã®ãµã¼ãã¹ãèªåã§VPC ã¨ã³ããã¤ã³ããå©ç¨ããããã«å¿
è¦ãªãããtrue
ã«è¨å®ãã¾ãããã
ECSã¿ã¹ã¯ã®ãã¼ã«ãå¤æ´
次ã«ECSã¿ã¹ã¯ã®ãã¼ã«ã«ã¢ã¿ããããã¦ããããªã·ã¼ãå¤æ´ãã¾ãã
./ecs/xxxxx/main.tf
variable "bedrock_vpc_endpoint_id" { type = string } data "aws_iam_policy_document" "iam_policy_document" { statement { actions = [ ãã ç¥ ãã "ec2:CreateNetworkInterface", "ec2:DescribeNetworkInterfaces", "ec2:DeleteNetworkInterface", "ec2:*VpcEndpoint*" ] resources = ["*"] } // Bedrockã¸ã®ã¢ã¯ã»ã¹ãVPC ã¨ã³ããã¤ã³ãçµç±ã®ã¿ã«å¶é statement { effect = "Allow" actions = [ "bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream" ] sid = "AllowTask" resources = ["*"] condition { test = "ForAnyValue:StringEquals" values = [var.bedrock_vpc_endpoint_id] variable = "aws:SourceVpce" } } }
ååé¨åã§ã¯ãECSã¿ã¹ã¯ããVPCã¨ã³ããã¤ã³ããå©ç¨ã§ãããããªstatementã追å ãã¦ãã¾ãã
ã¾ããå¾åé¨åã§ã¯ECSã¿ã¹ã¯ããBedrockã¸ã®ã¢ã¯ã»ã¹ãVPC ã¨ã³ããã¤ã³ãçµç±ã®ã¿ã«å¶éããæå³ãã¬ã¤ã³ã¿ã¼ãããã¸ã®ã¢ã¯ã»ã¹ãçºçããªãããã«ãã¦ãã¾ãã
ãã ãããã®statementã¯ããã¾ã§VPCã¨ã³ããã¤ã³ãããBedrockã«ã¢ã¯ã»ã¹ã§ããããã«ãã¦ããã ããªã®ã§ãä»ã«ç¡æ¡ä»¶ã§Bedrockã«ã¢ã¯ã»ã¹ã許å¯ãããããªstatementãè¨è¿°ãã¦ããå ´åã«ã¯åé¤ãã¦ããã¾ãããã
ä½æããé¨åãçµã¿åããã
æå¾ã«ããã¾ã§è¨è¿°ããVPC ã¨ã³ããã¤ã³ããå®éã«ä½æãã¾ãã
./main.tf
// Bedrockã«æ¥ç¶ããããã®VPCã¨ã³ããã¤ã³ã module "bedrock_vpc_endpoint" { source = "./vpc_endpoint/bedrock" vpc = { vpc_id = <使ç¨ããVPCã®IDãæå®> name = <使ç¨ããVPCã®ååãæå®> private_subnet_ids = <使ç¨ããVPCå ã®ãµãããããæå®ï¼åºæ¬çã«ã¯ECSãåå¨ãããµããããï¼> } trusted_role_arns = [ <ECS ã¿ã¹ã¯ãã¼ã«ã®arn> ] trusted_security_group_id = <ECSã«è¨å®ããSecurity Groupã®ID> }
çµããã«
ä»åã¯ECSã³ã³ããã¨Bedrockã®éã®PrivateLinkã確ç«ããæ¹æ³ããç´¹ä»ãã¾ããã
ã¤ã³ã¿ã¼ããããçµç±ããªããã¨ã§ã»ãã¥ãªãã£å¼·åã«ã¤ãªãããããBedrockãå©ç¨ããå ´åã«ã¯è¨å®ããã¨è¯ãã§ãããã