この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、森田です。
この記事では、別アカウントからVPC内のサービスへセキュアにアクセスする方法の1つである
PrivateLink接続について実際に構築し試していきます。
また、構築には、CloudFormationで行っておりますので、実際にお試し可能です。
構成図
以下、構成図となります。CloudFormationでは、Service Provider側のリソースを作成します。
用意するもの
- AWSアカウント2つ(同じアカウントからでも接続可能です)
- WEBサーバ構築済みのAMI
- 以下のCloudFormationテンプレート
CloudFormationテンプレート
AWSTemplateFormatVersion:
"2010-09-09"
Description:
AWS PrivateLink For SaaS
Parameters:
EC2AMI:
Type: String
PJPrefix:
Type: String
InstanceType:
Type: String
KeyPairName:
Type: String
AllowAccountID:
Type: String
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: "10.0.0.0/16"
Tags:
- Key: Name
Value: !Sub "${PJPrefix}-vpc"
PrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: "ap-northeast-1a"
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
Tags:
- Key: Name
Value: !Sub "${PJPrefix}-subnet"
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${PJPrefix}-table"
PrivateSubnetTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet
RouteTableId: !Ref PrivateRouteTable
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "privatelink"
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: "0.0.0.0/0"
Tags:
- Key: Name
Value: !Sub "${PJPrefix}-ec2"
EC2Instance:
Type: AWS::EC2::Instance
Properties:
Tags:
- Key: Name
Value: !Sub "${PJPrefix}-App"
ImageId: !Ref EC2AMI
InstanceType: !Ref InstanceType
KeyName: !Ref KeyPairName
DisableApiTermination: false
EbsOptimized: false
SecurityGroupIds:
- !Ref SecurityGroup
SubnetId: !Ref PrivateSubnet
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
VpcId: !Ref VPC
Name: !Sub "${PJPrefix}-tg"
Protocol: TCP
Port: 80
Tags:
- Key: Name
Value: !Sub "${PJPrefix}-tg"
Targets:
- Id: !Ref EC2Instance
Port: 80
NLB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub "${PJPrefix}-nlb"
Tags:
- Key: Name
Value: !Sub "${PJPrefix}-nlb"
Scheme: "internal"
LoadBalancerAttributes:
- Key: "deletion_protection.enabled"
Value: false
Subnets:
- !Ref PrivateSubnet
Type: network
NLBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref TargetGroup
Type: forward
LoadBalancerArn: !Ref NLB
Port: 80
Protocol: TCP
VPCEndpoint:
Type: AWS::EC2::VPCEndpointService
Properties:
AcceptanceRequired: true
NetworkLoadBalancerArns:
- !Ref NLB
VPCEndpointPermission:
Type: AWS::EC2::VPCEndpointServicePermissions
Properties:
AllowedPrincipals:
- !Sub "arn:aws:iam::${AllowAccountID}:root"
ServiceId: !Ref VPCEndpoint
パラメータとして、EC2のAMI IDを渡すように設定しています。
事前にWEBサーバの設定などを済ませて、イメージを作成しておきましょう。
また、事前にエンドポイントに対して、許可するアカウントIDも入力します。
やってみる
1. Service Provider側
まずは、CloudFormationでスタックを作成します。
作成後、VPCエンドポイントサービスが構成されているので、そのサービス名をメモしておきます。
2. 接続する側(Account A)
続いて、別のアカウントでログインを行い、VPCエンドポイントを作成します。
その際に先ほどメモしておいたサービス名を入力し、DNSの非有効化、配置するVPCやサブネット、セキュリティグループの設定などを行います。
3. Service Provider側
Service Provider側でエンドポイント接続の許可が必要ですので、承諾を選択します。
しばらく待つと、ステータスが使用可能になるので、実際に別アカウント内のEC2から動作を確認してみます。
4. 接続する側(Account A)のEC2
接続する側(Account A)のEC2へ接続し、curlでコンソールにあるDNSへリクエストを行います。
すると、正常に動作すれば、以下のようにサービスの結果を得ることができます。
# 別アカウントのEC2へ接続
$ ssh ec2-user@x.x.x.x -i xxx.pem
# curlでDNSへリクエスト
$ curl vpce-hoge1234567890.ap-northeast-1.vpce.amazonaws.com
Hello, PrivateLink!!
まとめ
今回は、CloudFormationでPrivateLinkを試してみましたが、想定したよりも簡単に素早く構成できました。
PrivateLink接続を用いることで、SaaSサービスへセキュアに接続したり、ネットワーク管理を楽にできるなど多くのメリットがありそうですね。