AWS PrivateLinkを利用して、他のAWS VPCに対して安全にサービスを提供する。
#1.環境#
AWSTemplateFormatVersion: '2010-09-09'
Description: 'For making 3 ec2 on 2 VPC. One VPC is a Client VPC which has 1 ec2.
The other is a Provider VPC which has 2 ec2. '
Mappings:
AWSInstanceType2Arch:
t3.medium:
Arch: HVM64
t3.micro:
Arch: HVM64
t3.small:
Arch: HVM64
t3a.micro:
Arch: HVM64
AWSRegionArch2AMI:
us-east-1:
HVM64: ami-0a887e401f7654935
us-west-2:
HVM64: ami-0e8c04af2729ff1bb
Outputs:
AZ:
Description: Availability Zone of the Client EC2 instance
Value: !Join
- ''
- - !GetAtt 'ClientInstance.AvailabilityZone'
ClientIP:
Description: Client EC2 IPaddress
Value: !Join
- ''
- - !GetAtt 'ClientInstance.PublicIp'
ProviderEC2One:
Description: 'Web server #1 on ProviderVPC'
Value: !Join
- ''
- - http://
- !GetAtt 'ProviderInstanceOne.PublicIp'
ProviderEC2Two:
Description: 'Web server #2 on ProviderVPC'
Value: !Join
- ''
- - http://
- !GetAtt 'ProviderInstanceTwo.PublicIp'
Parameters:
InstanceType:
AllowedValues:
- t3a.micro
- t3.micro
- t3.small
- t3.medium
ConstraintDescription: must be a valid EC2 instance type.
Default: t3.micro
Description: WebServer EC2 instance type
Type: String
SSHLocation:
AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
Default: '0.0.0.0/0'
Description: ' The IP address range that can be used to SSH to the EC2 instances'
MaxLength: '18'
MinLength: '9'
Type: String
Resources:
AttachGateway:
Properties:
InternetGatewayId: !Ref 'InternetGateway'
VpcId: !Ref 'ClientVPC'
Type: AWS::EC2::VPCGatewayAttachment
ClientInstance:
Properties:
ImageId: !FindInMap
- AWSRegionArch2AMI
- !Ref 'AWS::Region'
- !FindInMap
- AWSInstanceType2Arch
- !Ref 'InstanceType'
- Arch
InstanceType: !Ref 'InstanceType'
NetworkInterfaces:
- AssociatePublicIpAddress: 'true'
DeleteOnTermination: 'true'
DeviceIndex: '0'
GroupSet:
- !Ref 'InstanceSecurityGroup'
SubnetId: !Ref 'ClientSubnet'
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
- Key: Name
Value: ClientEC2
UserData: !Base64
Fn::Join:
- ''
- - "#!/bin/bash -xe\n"
- "yum update -y\n"
- "\n"
Type: AWS::EC2::Instance
ClientSubnet:
Properties:
AvailabilityZone: us-west-2c
CidrBlock: 10.100.0.0/24
MapPublicIpOnLaunch: 'true'
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
- Key: Name
Value: ClientPublic
VpcId: !Ref 'ClientVPC'
Type: AWS::EC2::Subnet
ClientVPC:
Properties:
CidrBlock: 10.100.0.0/16
EnableDnsHostnames: 'true'
EnableDnsSupport: 'true'
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
- Key: Name
Value: ClientVPC
Type: AWS::EC2::VPC
InboundResponsePortsNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'false'
NetworkAclId: !Ref 'NetworkAcl'
PortRange:
From: '1024'
To: '65535'
Protocol: '6'
RuleAction: allow
RuleNumber: '102'
Type: AWS::EC2::NetworkAclEntry
InboundSSHNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'false'
NetworkAclId: !Ref 'NetworkAcl'
PortRange:
From: '22'
To: '22'
Protocol: '6'
RuleAction: allow
RuleNumber: '101'
Type: AWS::EC2::NetworkAclEntry
InstanceSecurityGroup:
Properties:
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
- CidrIp: !Ref 'SSHLocation'
FromPort: '22'
IpProtocol: tcp
ToPort: '22'
VpcId: !Ref 'ClientVPC'
Type: AWS::EC2::SecurityGroup
InternetGateway:
Properties:
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
Type: AWS::EC2::InternetGateway
NetworkAcl:
Properties:
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
VpcId: !Ref 'ClientVPC'
Type: AWS::EC2::NetworkAcl
OutBoundHTTPNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'true'
NetworkAclId: !Ref 'NetworkAcl'
PortRange:
From: '80'
To: '80'
Protocol: '6'
RuleAction: allow
RuleNumber: '100'
Type: AWS::EC2::NetworkAclEntry
OutBoundResponsePortsNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'true'
NetworkAclId: !Ref 'NetworkAcl'
PortRange:
From: '1024'
To: '65535'
Protocol: '6'
RuleAction: allow
RuleNumber: '102'
Type: AWS::EC2::NetworkAclEntry
ProviderAttachGateway:
Properties:
InternetGatewayId: !Ref 'ProviderInternetGateway'
VpcId: !Ref 'ProviderVPC'
Type: AWS::EC2::VPCGatewayAttachment
ProviderInboundHTTPNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'false'
NetworkAclId: !Ref 'ProviderNetworkAcl'
PortRange:
From: '80'
To: '80'
Protocol: '6'
RuleAction: allow
RuleNumber: '100'
Type: AWS::EC2::NetworkAclEntry
ProviderInboundResponsePortsNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'false'
NetworkAclId: !Ref 'ProviderNetworkAcl'
PortRange:
From: '1024'
To: '65535'
Protocol: '6'
RuleAction: allow
RuleNumber: '102'
Type: AWS::EC2::NetworkAclEntry
ProviderInboundSSHNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'false'
NetworkAclId: !Ref 'ProviderNetworkAcl'
PortRange:
From: '22'
To: '22'
Protocol: '6'
RuleAction: allow
RuleNumber: '101'
Type: AWS::EC2::NetworkAclEntry
ProviderInstanceOne:
Metadata:
AWS::CloudFormation::Init:
config:
files:
/etc/cfn/cfn-hup.conf:
content: !Join
- ''
- - "[main]\n"
- stack=
- !Ref 'AWS::StackId'
- "\n"
- region=
- !Ref 'AWS::Region'
- "\n"
group: root
mode: '000400'
owner: root
/etc/cfn/hooks.d/cfn-auto-reloader.conf:
content: !Join
- ''
- - "[cfn-auto-reloader-hook]\n"
- "triggers=post.update\n"
- "path=Resources.ProviderInstanceOne.Metadata.AWS::CloudFormation::Init\n"
- 'action=/opt/aws/bin/cfn-init -v '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource ProviderInstanceOne '
- ' --region '
- !Ref 'AWS::Region'
- "\n"
- "runas=root\n"
/var/www/html/index.html:
content: !Join
- "\n"
- - <img src="https://s3.amazonaws.com/cloudformation-examples/cloudformation_graphic.png"
alt="AWS CloudFormation Logo"/>
- <h1>Congratulations, you have successfully launched for AWS Summit
Tokyo Handson.</h1>
group: root
mode: '000644'
owner: root
packages:
yum:
httpd: []
services:
sysvinit:
cfn-hup:
enabled: 'true'
ensureRunning: 'true'
files:
- /etc/cfn/cfn-hup.conf
- /etc/cfn/hooks.d/cfn-auto-reloader.conf
httpd:
enabled: 'true'
ensureRunning: 'true'
Properties:
ImageId: !FindInMap
- AWSRegionArch2AMI
- !Ref 'AWS::Region'
- !FindInMap
- AWSInstanceType2Arch
- !Ref 'InstanceType'
- Arch
InstanceType: !Ref 'InstanceType'
NetworkInterfaces:
- AssociatePublicIpAddress: 'true'
DeleteOnTermination: 'true'
DeviceIndex: '0'
GroupSet:
- !Ref 'ProviderInstanceSecurityGroup'
SubnetId: !Ref 'ProviderSubnet'
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
- Key: Name
Value: Provider_1
UserData: !Base64
Fn::Join:
- ''
- - "#!/bin/bash -xe\n"
- "yum update -y\n"
- "yum update -y aws-cfn-bootstrap\n"
- '/opt/aws/bin/cfn-init -v '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource ProviderInstanceOne '
- ' --region '
- !Ref 'AWS::Region'
- "\n"
- '/opt/aws/bin/cfn-signal -e $? '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource ProviderInstanceOne '
- ' --region '
- !Ref 'AWS::Region'
- "\n"
Type: AWS::EC2::Instance
ProviderInstanceSecurityGroup:
Properties:
GroupDescription: Enable SSH access via port 22
SecurityGroupIngress:
- CidrIp: !Ref 'SSHLocation'
FromPort: '22'
IpProtocol: tcp
ToPort: '22'
- CidrIp: '0.0.0.0/0'
FromPort: '80'
IpProtocol: tcp
ToPort: '80'
VpcId: !Ref 'ProviderVPC'
Type: AWS::EC2::SecurityGroup
ProviderInstanceTwo:
Metadata:
AWS::CloudFormation::Init:
config:
files:
/etc/cfn/cfn-hup.conf:
content: !Join
- ''
- - "[main]\n"
- stack=
- !Ref 'AWS::StackId'
- "\n"
- region=
- !Ref 'AWS::Region'
- "\n"
group: root
mode: '000400'
owner: root
/etc/cfn/hooks.d/cfn-auto-reloader.conf:
content: !Join
- ''
- - "[cfn-auto-reloader-hook]\n"
- "triggers=post.update\n"
- "path=Resources.ProviderInstanceOne.Metadata.AWS::CloudFormation::Init\n"
- 'action=/opt/aws/bin/cfn-init -v '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource ProviderInstanceOne '
- ' --region '
- !Ref 'AWS::Region'
- "\n"
- "runas=root\n"
/var/www/html/index.html:
content: !Join
- "\n"
- - <img src="https://s3.amazonaws.com/cloudformation-examples/cloudformation_graphic.png"
alt="AWS CloudFormation Logo"/>
- <h1>Congratulations, you have successfully launched for AWS Summit
Tokyo Handson.</h1>
group: root
mode: '000644'
owner: root
packages:
yum:
httpd: []
services:
sysvinit:
cfn-hup:
enabled: 'true'
ensureRunning: 'true'
files:
- /etc/cfn/cfn-hup.conf
- /etc/cfn/hooks.d/cfn-auto-reloader.conf
httpd:
enabled: 'true'
ensureRunning: 'true'
Properties:
ImageId: !FindInMap
- AWSRegionArch2AMI
- !Ref 'AWS::Region'
- !FindInMap
- AWSInstanceType2Arch
- !Ref 'InstanceType'
- Arch
InstanceType: !Ref 'InstanceType'
NetworkInterfaces:
- AssociatePublicIpAddress: 'true'
DeleteOnTermination: 'true'
DeviceIndex: '0'
GroupSet:
- !Ref 'ProviderInstanceSecurityGroup'
SubnetId: !Ref 'ProviderSubnet'
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
- Key: Name
Value: Provider_2
UserData: !Base64
Fn::Join:
- ''
- - "#!/bin/bash -xe\n"
- "yum update -y\n"
- "yum update -y aws-cfn-bootstrap\n"
- '/opt/aws/bin/cfn-init -v '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource ProviderInstanceTwo '
- ' --region '
- !Ref 'AWS::Region'
- "\n"
- '/opt/aws/bin/cfn-signal -e $? '
- ' --stack '
- !Ref 'AWS::StackName'
- ' --resource ProviderInstanceTwo '
- ' --region '
- !Ref 'AWS::Region'
- "\n"
Type: AWS::EC2::Instance
ProviderInternetGateway:
Properties:
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
Type: AWS::EC2::InternetGateway
ProviderNetworkAcl:
Properties:
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
VpcId: !Ref 'ProviderVPC'
Type: AWS::EC2::NetworkAcl
ProviderOutBoundHTTPNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'true'
NetworkAclId: !Ref 'ProviderNetworkAcl'
PortRange:
From: '80'
To: '80'
Protocol: '6'
RuleAction: allow
RuleNumber: '100'
Type: AWS::EC2::NetworkAclEntry
ProviderOutBoundHTTPSNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'true'
NetworkAclId: !Ref 'ProviderNetworkAcl'
PortRange:
From: '443'
To: '443'
Protocol: '6'
RuleAction: allow
RuleNumber: '101'
Type: AWS::EC2::NetworkAclEntry
ProviderOutBoundResponsePortsNetworkAclEntry:
Properties:
CidrBlock: '0.0.0.0/0'
Egress: 'true'
NetworkAclId: !Ref 'ProviderNetworkAcl'
PortRange:
From: '1024'
To: '65535'
Protocol: '6'
RuleAction: allow
RuleNumber: '102'
Type: AWS::EC2::NetworkAclEntry
ProviderRoute:
DependsOn: AttachGateway
Properties:
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref 'ProviderInternetGateway'
RouteTableId: !Ref 'ProviderRouteTable'
Type: AWS::EC2::Route
ProviderRouteTable:
Properties:
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
VpcId: !Ref 'ProviderVPC'
Type: AWS::EC2::RouteTable
ProviderSubnet:
Properties:
AvailabilityZone: us-west-2c
CidrBlock: 10.100.0.0/24
MapPublicIpOnLaunch: 'true'
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
- Key: Name
Value: ProviderPublic
VpcId: !Ref 'ProviderVPC'
Type: AWS::EC2::Subnet
ProviderSubnetNetworkAclAssociation:
Properties:
NetworkAclId: !Ref 'ProviderNetworkAcl'
SubnetId: !Ref 'ProviderSubnet'
Type: AWS::EC2::SubnetNetworkAclAssociation
ProviderSubnetRouteTableAssociation:
Properties:
RouteTableId: !Ref 'ProviderRouteTable'
SubnetId: !Ref 'ProviderSubnet'
Type: AWS::EC2::SubnetRouteTableAssociation
ProviderVPC:
Properties:
CidrBlock: 10.100.0.0/16
EnableDnsHostnames: 'true'
EnableDnsSupport: 'true'
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
- Key: Name
Value: ProviderVPC
Type: AWS::EC2::VPC
Route:
DependsOn: AttachGateway
Properties:
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref 'InternetGateway'
RouteTableId: !Ref 'RouteTable'
Type: AWS::EC2::Route
RouteTable:
Properties:
Tags:
- Key: Application
Value: !Ref 'AWS::StackId'
VpcId: !Ref 'ClientVPC'
Type: AWS::EC2::RouteTable
SMInstanceProfile:
Properties:
Path: /
Roles:
- !Ref 'SMRole'
Type: AWS::IAM::InstanceProfile
SMRole:
Properties:
AssumeRolePolicyDocument:
Statement:
- Action:
- sts:AssumeRole
Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Version: '2012-10-17'
Path: /
Policies:
- PolicyDocument:
Statement:
- Action:
- ssm:UpdateInstanceInformation
- ssmmessages:CreateControlChannel
- ssmmessages:CreateDataChannel
- ssmmessages:OpenControlChannel
- ssmmessages:OpenDataChannel
Effect: Allow
Resource: '*'
- Action:
- s3:GetEncryptionConfiguration
Effect: Allow
Resource: '*'
Version: '2012-10-17'
PolicyName: root-0317a
Type: AWS::IAM::Role
SubnetNetworkAclAssociation:
Properties:
NetworkAclId: !Ref 'NetworkAcl'
SubnetId: !Ref 'ClientSubnet'
Type: AWS::EC2::SubnetNetworkAclAssociation
SubnetRouteTableAssociation:
Properties:
RouteTableId: !Ref 'RouteTable'
SubnetId: !Ref 'ClientSubnet'
Type: AWS::EC2::SubnetRouteTableAssociation
#2.NLBの作成とVPC エンドポイントサービスを設定する#
##2-1.NLBを作成する##
・ロードバランサーの設定
VPCは Provider-VPCを選択
・セキュリティ設定の構成
SSLは利用しないので、そのまま進む。
・ルーティングの設定
ターゲットグループ名だけ入力し、後はデフォルトとする。
・確認
完了。
##2-2.VPC エンドポイントサービスを作成する##
VPCの「エンドポイントサービスの作成」から「2-1.NLBを作成する」で作成したNLBを紐づける。
#3.VPC エンドポイントを作成する#
「2.VPC エンドポイントサービス設定を作成し、NLBを紐づける」で作成したエンドポイントサービスをClientPublicのVPCを指定する。
セキュリティグループは、VPC内からのHTTP通信を受け付けるようにする。
#4.動作確認#
Client側のEC2でEC2 Instance Connectで接続し、エンドポイントにcurlで接続する。