Description: Bedrock Access Gateway - OpenAI-compatible RESTful APIs for Amazon Bedrock Parameters: ApiKeySecretArn: Type: String AllowedPattern: ^arn:aws:secretsmanager:.*$ Description: The secret ARN in Secrets Manager used to store the API Key ContainerImageUri: Type: String Description: The ECR image URI for the ECS/Fargate task (e.g., 123456789012.dkr.ecr.us-east-1.amazonaws.com/bedrock-proxy-api-ecs:latest) DefaultModelId: Type: String Default: anthropic.claude-3-sonnet-20240229-v1:0 Description: The default model ID, please make sure the model ID is supported in the current region Resources: VPCB9E5F0B4: Type: AWS::EC2::VPC Properties: CidrBlock: 10.250.0.0/16 EnableDnsHostnames: true EnableDnsSupport: true InstanceTenancy: default Tags: - Key: Name Value: BedrockProxyFargate/VPC VPCPublicSubnet1SubnetB4246D30: Type: AWS::EC2::Subnet Properties: AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: "" CidrBlock: 10.250.0.0/24 MapPublicIpOnLaunch: true Tags: - Key: aws-cdk:subnet-name Value: Public - Key: aws-cdk:subnet-type Value: Public - Key: Name Value: BedrockProxyFargate/VPC/PublicSubnet1 VpcId: Ref: VPCB9E5F0B4 VPCPublicSubnet1RouteTableFEE4B781: Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: BedrockProxyFargate/VPC/PublicSubnet1 VpcId: Ref: VPCB9E5F0B4 VPCPublicSubnet1RouteTableAssociation0B0896DC: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: Ref: VPCPublicSubnet1RouteTableFEE4B781 SubnetId: Ref: VPCPublicSubnet1SubnetB4246D30 VPCPublicSubnet1DefaultRoute91CEF279: Type: AWS::EC2::Route Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: Ref: VPCIGWB7E252D3 RouteTableId: Ref: VPCPublicSubnet1RouteTableFEE4B781 DependsOn: - VPCVPCGW99B986DC VPCPublicSubnet2Subnet74179F39: Type: AWS::EC2::Subnet Properties: AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: "" CidrBlock: 10.250.1.0/24 MapPublicIpOnLaunch: true Tags: - Key: aws-cdk:subnet-name Value: Public - Key: aws-cdk:subnet-type Value: Public - Key: Name Value: BedrockProxyFargate/VPC/PublicSubnet2 VpcId: Ref: VPCB9E5F0B4 VPCPublicSubnet2RouteTable6F1A15F1: Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: BedrockProxyFargate/VPC/PublicSubnet2 VpcId: Ref: VPCB9E5F0B4 VPCPublicSubnet2RouteTableAssociation5A808732: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: Ref: VPCPublicSubnet2RouteTable6F1A15F1 SubnetId: Ref: VPCPublicSubnet2Subnet74179F39 VPCPublicSubnet2DefaultRouteB7481BBA: Type: AWS::EC2::Route Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: Ref: VPCIGWB7E252D3 RouteTableId: Ref: VPCPublicSubnet2RouteTable6F1A15F1 DependsOn: - VPCVPCGW99B986DC VPCIGWB7E252D3: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: BedrockProxyFargate/VPC VPCVPCGW99B986DC: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: Ref: VPCIGWB7E252D3 VpcId: Ref: VPCB9E5F0B4 ProxyExecRole6947A5BE: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Version: "2012-10-17" ProxyExecRoleDefaultPolicyED41DFE7: Type: AWS::IAM::Policy Properties: PolicyDocument: Statement: - Action: - logs:CreateLogStream - logs:PutLogEvents Effect: Allow Resource: "*" - Action: - secretsmanager:GetSecretValue - secretsmanager:DescribeSecret Effect: Allow Resource: Ref: ApiKeySecretArn - Action: - ecr:BatchCheckLayerAvailability - ecr:GetDownloadUrlForLayer - ecr:BatchGetImage Effect: Allow Resource: Fn::Join: - "" - - "arn:aws:ecr:" - Fn::Select: - 3 - Fn::Split: - "." - Fn::Select: - 0 - Fn::Split: - "/" - Ref: ContainerImageUri - ":" - Fn::Select: - 0 - Fn::Split: - "." - Fn::Select: - 0 - Fn::Split: - "/" - Ref: ContainerImageUri - ":repository/" - Fn::Select: - 0 - Fn::Split: - ":" - Fn::Select: - 1 - Fn::Split: - "/" - Ref: ContainerImageUri - Action: ecr:GetAuthorizationToken Effect: Allow Resource: "*" Version: "2012-10-17" PolicyName: ProxyExecRoleDefaultPolicyED41DFE7 Roles: - Ref: ProxyExecRole6947A5BE ProxyTaskRole5DB6A540: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Version: "2012-10-17" ProxyTaskRoleDefaultPolicy933321B8: Type: AWS::IAM::Policy Properties: PolicyDocument: Statement: - Action: - bedrock:ListFoundationModels - bedrock:ListInferenceProfiles Effect: Allow Resource: "*" - Action: - bedrock:InvokeModel - bedrock:InvokeModelWithResponseStream Effect: Allow Resource: - arn:aws:bedrock:*::foundation-model/* - arn:aws:bedrock:*:*:inference-profile/* - arn:aws:bedrock:*:*:application-inference-profile/* Version: "2012-10-17" PolicyName: ProxyTaskRoleDefaultPolicy933321B8 Roles: - Ref: ProxyTaskRole5DB6A540 ProxyBedrockCluster893F4261: Type: AWS::ECS::Cluster ProxyBedrockClusterD9C31EFF: Type: AWS::ECS::ClusterCapacityProviderAssociations Properties: CapacityProviders: - FARGATE - FARGATE_SPOT Cluster: Ref: ProxyBedrockCluster893F4261 DefaultCapacityProviderStrategy: [] ProxyTaskDef9F2A72E5: Type: AWS::ECS::TaskDefinition Properties: ContainerDefinitions: - Environment: - Name: DEBUG Value: "false" - Name: DEFAULT_MODEL Value: Ref: DefaultModelId - Name: DEFAULT_EMBEDDING_MODEL Value: cohere.embed-multilingual-v3 - Name: ENABLE_CROSS_REGION_INFERENCE Value: "true" - Name: ENABLE_APPLICATION_INFERENCE_PROFILES Value: "true" Essential: true Image: Ref: ContainerImageUri Name: proxy-api PortMappings: - ContainerPort: 80 HostPort: 80 Protocol: tcp Secrets: - Name: API_KEY ValueFrom: Fn::Join: - "" - - Ref: ApiKeySecretArn - ":api_key::" Cpu: "1024" ExecutionRoleArn: Fn::GetAtt: - ProxyExecRole6947A5BE - Arn Family: BedrockProxyFargateProxyTaskDefCD902792 Memory: "2048" NetworkMode: awsvpc RequiresCompatibilities: - FARGATE RuntimePlatform: CpuArchitecture: ARM64 OperatingSystemFamily: LINUX TaskRoleArn: Fn::GetAtt: - ProxyTaskRole5DB6A540 - Arn ProxyApiService8651D882: Type: AWS::ECS::Service Properties: CapacityProviderStrategy: - CapacityProvider: FARGATE Weight: 1 Cluster: Ref: ProxyBedrockCluster893F4261 DeploymentConfiguration: Alarms: AlarmNames: [] Enable: false Rollback: false MaximumPercent: 200 MinimumHealthyPercent: 50 DesiredCount: 1 EnableECSManagedTags: false HealthCheckGracePeriodSeconds: 60 LoadBalancers: - ContainerName: proxy-api ContainerPort: 80 TargetGroupArn: Ref: ProxyALBListenerTargetsGroup187739FA NetworkConfiguration: AwsvpcConfiguration: AssignPublicIp: ENABLED SecurityGroups: - Fn::GetAtt: - ProxyApiServiceSecurityGroup51EBD9B8 - GroupId Subnets: - Ref: VPCPublicSubnet1SubnetB4246D30 - Ref: VPCPublicSubnet2Subnet74179F39 TaskDefinition: Ref: ProxyTaskDef9F2A72E5 DependsOn: - ProxyALBListener933E9515 - ProxyALBListenerTargetsGroup187739FA - ProxyTaskRoleDefaultPolicy933321B8 - ProxyTaskRole5DB6A540 ProxyApiServiceSecurityGroup51EBD9B8: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: BedrockProxyFargate/Proxy/ApiService/SecurityGroup SecurityGroupEgress: - CidrIp: 0.0.0.0/0 Description: Allow all outbound traffic by default IpProtocol: "-1" VpcId: Ref: VPCB9E5F0B4 DependsOn: - ProxyTaskRoleDefaultPolicy933321B8 - ProxyTaskRole5DB6A540 ProxyApiServiceSecurityGroupfromBedrockProxyFargateProxyALBSecurityGroup9C12825880081F8FE2: Type: AWS::EC2::SecurityGroupIngress Properties: Description: Load balancer to target FromPort: 80 GroupId: Fn::GetAtt: - ProxyApiServiceSecurityGroup51EBD9B8 - GroupId IpProtocol: tcp SourceSecurityGroupId: Fn::GetAtt: - ProxyALBSecurityGroup0D6CA3DA - GroupId ToPort: 80 DependsOn: - ProxyTaskRoleDefaultPolicy933321B8 - ProxyTaskRole5DB6A540 ProxyALB87756780: Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: LoadBalancerAttributes: - Key: deletion_protection.enabled Value: "false" - Key: idle_timeout.timeout_seconds Value: "600" Scheme: internet-facing SecurityGroups: - Fn::GetAtt: - ProxyALBSecurityGroup0D6CA3DA - GroupId Subnets: - Ref: VPCPublicSubnet1SubnetB4246D30 - Ref: VPCPublicSubnet2Subnet74179F39 Type: application DependsOn: - VPCPublicSubnet1DefaultRoute91CEF279 - VPCPublicSubnet1RouteTableAssociation0B0896DC - VPCPublicSubnet2DefaultRouteB7481BBA - VPCPublicSubnet2RouteTableAssociation5A808732 ProxyALBSecurityGroup0D6CA3DA: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Automatically created Security Group for ELB BedrockProxyFargateProxyALB481672E7 SecurityGroupIngress: - CidrIp: 0.0.0.0/0 Description: Allow from anyone on port 80 FromPort: 80 IpProtocol: tcp ToPort: 80 VpcId: Ref: VPCB9E5F0B4 ProxyALBSecurityGrouptoBedrockProxyFargateProxyApiServiceSecurityGroupDDA1C56480393D1E44: Type: AWS::EC2::SecurityGroupEgress Properties: Description: Load balancer to target DestinationSecurityGroupId: Fn::GetAtt: - ProxyApiServiceSecurityGroup51EBD9B8 - GroupId FromPort: 80 GroupId: Fn::GetAtt: - ProxyALBSecurityGroup0D6CA3DA - GroupId IpProtocol: tcp ToPort: 80 ProxyALBListener933E9515: Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - TargetGroupArn: Ref: ProxyALBListenerTargetsGroup187739FA Type: forward LoadBalancerArn: Ref: ProxyALB87756780 Port: 80 Protocol: HTTP ProxyALBListenerTargetsGroup187739FA: Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: HealthCheckEnabled: true HealthCheckIntervalSeconds: 60 HealthCheckPath: /health HealthCheckTimeoutSeconds: 30 Port: 80 Protocol: HTTP TargetGroupAttributes: - Key: stickiness.enabled Value: "false" TargetType: ip VpcId: Ref: VPCB9E5F0B4 Outputs: APIBaseUrl: Description: Proxy API Base URL (OPENAI_API_BASE) Value: Fn::Join: - "" - - http:// - Fn::GetAtt: - ProxyALB87756780 - DNSName - /api/v1