S3 Express One Zone 用の VPC エンドポイント Gateway 型を作成する CloudFormation テンプレートの紹介
CloudFormation で構築済みの VPC に S3 Express One Zone 用の Gateway 型の VPC エンドポイントを追加する機会がありました。CloudFormation で構築するテンプレートのサンプルを紹介します。
S3 Express One Zone とは
re:Invent 2023 において、Amazon S3 の新機能として、低レイテンシとハイパフォーマンスを実現する新しいストレージクラスが発表されました。このストレージクラスは、特に S3 におけるデータアクセスの速度を重視するユースケースに適しています。詳細については下記のブログをご覧ください。
S3 Express One Zone の VPC エンドポイントは別
通常の S3 用の VPC エンドポイントとは異なる VPC エンドポイントが別途必要になります。S3 Express One Zone のディレクトリバケットへの通信を VPC エンドポイント経由するには S3 Express One Zone 用の VPC エンドポイントも必要です。
検討背景
今回はゲノム解析のワークロードで Mountpoint for Amazon S3 を利用して、インプットファイルを S3 に保存しています。シーケンシャルなリードアクセスは良しとして、リード時にランダムアクセスが走るものは相性が悪かったです。
ランダムなデータアクセスリクエストを行うファイルベースのアプリケーションを S3 Standard と比較して最大で 6 倍高速化できます。 Mountpoint for Amazon S3 が S3 Express One Zone ストレージクラスのサポートを開始
そこで S3 Express One Zone で実用的な速度で運用可能か試す準備として EC2 から S3 Express One Zone の通信経路を VPC エンドポイント経由にして経路を最適化します。なにより EC2 と S3 間の通信コストがかからなくなるのは大きいです。
VPC エンドポイントを作成するテンプレート
CloudFormation で S3 Express One Zone 用の VPC エンドポイント Gateway 型を作成するには以下の様に記述します。
# S3 Express Gateway Type GatewayS3ExpressEndpoint: Type: AWS::EC2::VPCEndpoint Properties: RouteTableIds: # ルートテーブルに紐づけが必要 - !Ref PublicRouteTable1 - !Ref PrivateRouteTable1 - !Ref IsolatedRouteTable1 ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3express" # ここを S3 Expreess 指定する VpcEndpointType: Gateway VpcId: !Ref VPC # VPC の ID を指定
下記は通常の S3 用の VPC エンドポイント Gateway 型の記述です。差分はServiceName:
の箇所だけです。
# S3 Gateway Type GatewayS3Endpoint: Type: AWS::EC2::VPCEndpoint Properties: RouteTableIds: - !Ref PublicRouteTable1 - !Ref PrivateRouteTable1 - !Ref IsolatedRouteTable1 ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3" # ここが S3 指定になってる違いがある VpcEndpointType: Gateway VpcId: !Ref VPC
VPC 作成テンプレート全文
3 AZ 構成の VPC に S3 と S3 Exreppss One Zone の 2 つ Gateway 型の VPC エンドポイントをアタッチした構成 + α のサンプルテンプレートを参考までに記載します。
折りたたみ
--- AWSTemplateFormatVersion: "2010-09-09" Description: 3AZ Network 3 layers and VPC Endpoint with switching single Nat Gateway Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: NAT Gateway Setting Parameters: - EnableNatGateway Parameters: EnableNatGateway: Description: Enable NAT Gateway Type: String Default: false AllowedValues: [true, false] Mappings: Constant: EnvName: ProjectName: hpc Environment: dev Network: Cidrs: VPCCidr: 10.0.0.0/16 PublicSubnetCidr1: 10.0.1.0/24 PublicSubnetCidr2: 10.0.2.0/24 PublicSubnetCidr3: 10.0.3.0/24 PrivateSubnetCidr1: 10.0.17.0/24 PrivateSubnetCidr2: 10.0.18.0/24 PrivateSubnetCidr3: 10.0.19.0/24 IsolatedSubnetCidr1: 10.0.33.0/24 IsolatedSubnetCidr2: 10.0.34.0/24 IsolatedSubnetCidr3: 10.0.35.0/24 Conditions: EnableNatGateway: !Equals [true, !Ref EnableNatGateway] Resources: # ---------------------------------------------------------------------------------------- # VPC # ---------------------------------------------------------------------------------------- VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !FindInMap [ Network, Cidrs, VPCCidr] EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub - "${ProjectName}-${Environment}-vpc" - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] # ---------------------------------------------------------------------------------------- # Internet Gateway # ---------------------------------------------------------------------------------------- # Create InternetGateway & VPC Attach InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-igw - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] AttachGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway # ---------------------------------------------------------------------------------------- # NAT Gateway # ---------------------------------------------------------------------------------------- # Create NatGateway NatGateway1: Type: AWS::EC2::NatGateway Condition: EnableNatGateway Properties: AllocationId: !GetAtt NatGatewayEIP1.AllocationId SubnetId: !Ref PublicSubnet1 Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-natgw1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] NatGatewayEIP1: Type: AWS::EC2::EIP Condition: EnableNatGateway Properties: Domain: vpc Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-natgw-eip1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] # ---------------------------------------------------------------------------------------- # Route Table # ---------------------------------------------------------------------------------------- # Create Public RouteTable & Setting Routing PublicRouteTable1: Type: AWS::EC2::RouteTable DependsOn: AttachGateway Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-public-rtb1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] PublicRoute1: Type: AWS::EC2::Route DependsOn: AttachGateway Properties: RouteTableId: !Ref PublicRouteTable1 DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway # Create Private RouteTable & Setting Routing PrivateRouteTable1: Type: AWS::EC2::RouteTable DependsOn: AttachGateway Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-private-rtb1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] PrivateRouteNatGW1: Type: AWS::EC2::Route Condition: EnableNatGateway DependsOn: AttachGateway Properties: RouteTableId: !Ref PrivateRouteTable1 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway1 # Create Isolated RouteTable & Setting Routing IsolatedRouteTable1: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-isolated-rtb1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] # ---------------------------------------------------------------------------------------- # Public Subnet # ---------------------------------------------------------------------------------------- # Public 1 PublicSubnet1: Type: AWS::EC2::Subnet DependsOn: AttachGateway Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !FindInMap [ Network, Cidrs, PublicSubnetCidr1] MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-public-subnet1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] PublicSubnetRouteTableAssociation1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet1 RouteTableId: !Ref PublicRouteTable1 # Public 2 PublicSubnet2: Type: AWS::EC2::Subnet DependsOn: AttachGateway Properties: VpcId: !Ref VPC AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !FindInMap [ Network, Cidrs, PublicSubnetCidr2] MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-public-subnet2 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] PublicSubnetRouteTableAssociation2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet2 RouteTableId: !Ref PublicRouteTable1 # Public 3 PublicSubnet3: Type: AWS::EC2::Subnet DependsOn: AttachGateway Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ""] CidrBlock: !FindInMap [ Network, Cidrs, PublicSubnetCidr3] MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-public-subnet3 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] PublicSubnetRouteTableAssociation3: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet3 RouteTableId: !Ref PublicRouteTable1 # ---------------------------------------------------------------------------------------- # Private Subnet # ---------------------------------------------------------------------------------------- # Private 1 PrivateSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !FindInMap [ Network, Cidrs, PrivateSubnetCidr1] Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-private-subnet1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] PrivateSubnetRouteTableAssociation1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet1 RouteTableId: !Ref PrivateRouteTable1 # Private 2 PrivateSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !FindInMap [ Network, Cidrs, PrivateSubnetCidr2] Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-private-subnet2 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] PrivateSubnetRouteTableAssociation2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet2 RouteTableId: !Ref PrivateRouteTable1 # Private 3 PrivateSubnet3: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ""] CidrBlock: !FindInMap [ Network, Cidrs, PrivateSubnetCidr3] Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-private-subnet3 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] PrivateSubnetRouteTableAssociation3: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PrivateSubnet3 RouteTableId: !Ref PrivateRouteTable1 # ---------------------------------------------------------------------------------------- # Isolated Subnet # ---------------------------------------------------------------------------------------- # Isolated 1 IsolatedSubnet1: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [0, !GetAZs ""] CidrBlock: !FindInMap [ Network, Cidrs, IsolatedSubnetCidr1] Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-isolated-subnet1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] IsolatedSubnetRouteTableAssociation1: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref IsolatedSubnet1 RouteTableId: !Ref IsolatedRouteTable1 # Isolated 2 IsolatedSubnet2: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [1, !GetAZs ""] CidrBlock: !FindInMap [ Network, Cidrs, IsolatedSubnetCidr2] Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-isolated-subnet2 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] IsolatedSubnetRouteTableAssociation2: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref IsolatedSubnet2 RouteTableId: !Ref IsolatedRouteTable1 # Isolated 3 IsolatedSubnet3: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VPC AvailabilityZone: !Select [2, !GetAZs ""] CidrBlock: !FindInMap [ Network, Cidrs, IsolatedSubnetCidr3] Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-isolated-subnet3 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] - Key: Environment Value: !FindInMap [ Constant, EnvName, Environment] IsolatedSubnetRouteTableAssociation3: Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref IsolatedSubnet3 RouteTableId: !Ref IsolatedRouteTable1 # ---------------------------------------------------------------------------------------- # Network ACL # ---------------------------------------------------------------------------------------- # Public NACL PublicNetworkACL1: Type: AWS::EC2::NetworkAcl Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-public-nacl1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] NetworkACLEntryPublicIngress1: Type: AWS::EC2::NetworkAclEntry Properties: CidrBlock: "0.0.0.0/0" Egress: false NetworkAclId: !Ref PublicNetworkACL1 Protocol: -1 RuleAction: "allow" RuleNumber: 100 NetworkACLEntryPublicEgress1: Type: "AWS::EC2::NetworkAclEntry" Properties: CidrBlock: "0.0.0.0/0" Egress: true NetworkAclId: !Ref PublicNetworkACL1 Protocol: -1 RuleAction: "allow" RuleNumber: 100 # Private NACL PrivateNetworkACL1: Type: AWS::EC2::NetworkAcl Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-private-nacl1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] NetworkACLEntryPrivateIngress1: Type: AWS::EC2::NetworkAclEntry Properties: CidrBlock: "0.0.0.0/0" Egress: false NetworkAclId: !Ref PrivateNetworkACL1 Protocol: -1 RuleAction: "allow" RuleNumber: 100 NetworkACLEntryPrivateEgress1: Type: "AWS::EC2::NetworkAclEntry" Properties: CidrBlock: "0.0.0.0/0" Egress: true NetworkAclId: !Ref PrivateNetworkACL1 Protocol: -1 RuleAction: "allow" RuleNumber: 100 # Isolated NACL IsolatedNetworkACL1: Type: AWS::EC2::NetworkAcl Properties: VpcId: !Ref VPC Tags: - Key: Name Value: !Sub - ${ProjectName}-${Environment}-isolated-nacl1 - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] NetworkACLEntryIsolatedIngress1: Type: AWS::EC2::NetworkAclEntry Properties: CidrBlock: "0.0.0.0/0" Egress: false NetworkAclId: !Ref IsolatedNetworkACL1 Protocol: -1 RuleAction: "allow" RuleNumber: 100 NetworkACLEntryIsolatedEgress1: Type: "AWS::EC2::NetworkAclEntry" Properties: CidrBlock: "0.0.0.0/0" Egress: true NetworkAclId: !Ref IsolatedNetworkACL1 Protocol: -1 RuleAction: "allow" RuleNumber: 100 # NetworkACL Association PublicNetworkACLAssocation1: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PublicSubnet1 NetworkAclId: !Ref PublicNetworkACL1 PublicNetworkACLAssocation2: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PublicSubnet2 NetworkAclId: !Ref PublicNetworkACL1 PublicNetworkACLAssocation3: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PublicSubnet3 NetworkAclId: !Ref PublicNetworkACL1 PrivateNetworkACLAssocation1: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PrivateSubnet1 NetworkAclId: !Ref PrivateNetworkACL1 PrivateNetworkACLAssocation2: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PrivateSubnet2 NetworkAclId: !Ref PrivateNetworkACL1 PrivateNetworkACLAssocation3: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref PrivateSubnet3 NetworkAclId: !Ref PrivateNetworkACL1 IsolatedNetworkACLAssocation1: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref IsolatedSubnet1 NetworkAclId: !Ref IsolatedNetworkACL1 IsolatedNetworkACLAssocation2: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref IsolatedSubnet2 NetworkAclId: !Ref IsolatedNetworkACL1 IsolatedNetworkACLAssocation3: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: SubnetId: !Ref IsolatedSubnet3 NetworkAclId: !Ref IsolatedNetworkACL1 # ---------------------------------------------------------------------------------------- # VPC Endpoints # ---------------------------------------------------------------------------------------- # S3 Gateway Type GatewayS3Endpoint: Type: AWS::EC2::VPCEndpoint Properties: RouteTableIds: - !Ref PublicRouteTable1 - !Ref PrivateRouteTable1 - !Ref IsolatedRouteTable1 ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3" VpcEndpointType: Gateway VpcId: !Ref VPC # S3 Express Gateway Type GatewayS3ExpressEndpoint: Type: AWS::EC2::VPCEndpoint Properties: RouteTableIds: - !Ref PublicRouteTable1 - !Ref PrivateRouteTable1 - !Ref IsolatedRouteTable1 ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3express" VpcEndpointType: Gateway VpcId: !Ref VPC # ------------------------------------------------------------# # S3 Bucket for VPC Flow Logs # ------------------------------------------------------------# S3Bucket: Type: AWS::S3::Bucket DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: BucketName: !Sub - ${ProjectName}-${Environment}-vpc-flowlogs-${AWS::AccountId} - ProjectName: !FindInMap [ Constant, EnvName, ProjectName] Environment: !FindInMap [ Constant, EnvName, Environment] OwnershipControls: Rules: - ObjectOwnership: "BucketOwnerEnforced" PublicAccessBlockConfiguration: BlockPublicAcls: True BlockPublicPolicy: True IgnorePublicAcls: True RestrictPublicBuckets: True VersioningConfiguration: Status: Enabled BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: "AES256" BucketKeyEnabled: false LifecycleConfiguration: Rules: - Id: AbortIncompleteMultipartUpload AbortIncompleteMultipartUpload: DaysAfterInitiation: 7 Status: "Enabled" - Id: CurrentVersionExpiration ExpirationInDays: 365 Status: "Enabled" - Id: NoncurrentVersionExpiration NoncurrentVersionExpiration: NoncurrentDays: 7 Status: "Enabled" # ------------------------------------------------------------# # VPC Flow Logs # ------------------------------------------------------------# VPCFlowLogs: Type: "AWS::EC2::FlowLog" Properties: LogDestinationType: s3 LogDestination: !GetAtt S3Bucket.Arn ResourceType: "VPC" ResourceId: !Ref VPC TrafficType: ALL DestinationOptions: { "FileFormat": "plain-text", "HiveCompatiblePartitions": false, "PerHourPartition": true, } # ---------------------------------------------------------------------------------------- # Exports # ---------------------------------------------------------------------------------------- Outputs: ExportVPC: Value: !Ref VPC Export: Name: !Sub ${AWS::StackName}-VPC ExportPublicSubnet1: Value: !Ref PublicSubnet1 Export: Name: !Sub ${AWS::StackName}-PublicSubnet1 ExportPublicSubnet2: Value: !Ref PublicSubnet2 Export: Name: !Sub ${AWS::StackName}-PublicSubnet2 ExportPublicSubnet3: Value: !Ref PublicSubnet3 Export: Name: !Sub ${AWS::StackName}-PublicSubnet3 ExportPublicRoutetable1: Value: !Ref PublicRouteTable1 Export: Name: !Sub ${AWS::StackName}-PublicRouteTable1 ExportPrivateSubnet1: Value: !Ref PrivateSubnet1 Export: Name: !Sub ${AWS::StackName}-PrivateSubnet1 ExportPrivateSubnet2: Value: !Ref PrivateSubnet2 Export: Name: !Sub ${AWS::StackName}-PrivateSubnet2 ExportPrivateSubnet3: Value: !Ref PrivateSubnet3 Export: Name: !Sub ${AWS::StackName}-PrivateSubnet3 ExportPrivateRoutetable1: Value: !Ref PrivateRouteTable1 Export: Name: !Sub ${AWS::StackName}-PrivateRouteTable1 ExportIsolatedSubnet1: Value: !Ref IsolatedSubnet1 Export: Name: !Sub ${AWS::StackName}-IsolatedSubnet1 ExportIsolatedSubnet2: Value: !Ref IsolatedSubnet2 Export: Name: !Sub ${AWS::StackName}-IsolatedSubnet2 ExportIsolatedSubnet3: Value: !Ref IsolatedSubnet2 Export: Name: !Sub ${AWS::StackName}-IsolatedSubnet3 ExportIsolatedRoutetable1: Value: !Ref IsolatedRouteTable1 Export: Name: !Sub ${AWS::StackName}-IsolatedRouteTable1
S3 Express One Zone の IAM ポリシー
EC2 から S3 Express One Zone のディレクトリバケットへアクセスするには新たな IAM ポリシーが必要になります。詳細は以下のブログを参照ください。
おわりに
S3 Express One Zone は通常の S3 の VPC エンドポイントを別であること、S3 Express One Zone 用の VPC エンドポイントの作成 CloudFormation テンプレートの例をお客様へご案内したかったです。ですが、ちょうど良いサンプルがなかったので作成しました。最近は CloudFormation 以外で IaC のコードを書くことが多いような気もしますが、CloudFormation ユーザーの方々の参考になれば幸いです。