LoginSignup
0
0

More than 3 years have passed since last update.

AWS VPC PrivateLink ~ demo

Last updated at Posted at 2020-09-28

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を選択
スクリーンショット 2020-09-28 110427.png

・セキュリティ設定の構成
SSLは利用しないので、そのまま進む。

・ルーティングの設定
ターゲットグループ名だけ入力し、後はデフォルトとする。

・ターゲットの登録
LBさせる2つのインスタンスを追加。
スクリーンショット 2020-09-28 111137.png

・確認
完了。

2-2.VPC エンドポイントサービスを作成する

VPCの「エンドポイントサービスの作成」から「2-1.NLBを作成する」で作成したNLBを紐づける。
スクリーンショット 2020-09-28 111137.png

3.VPC エンドポイントを作成する

「2.VPC エンドポイントサービス設定を作成し、NLBを紐づける」で作成したエンドポイントサービスをClientPublicのVPCを指定する。
スクリーンショット 2020-09-28 114110.png

セキュリティグループは、VPC内からのHTTP通信を受け付けるようにする。
スクリーンショット 2020-09-28 114635.png

エンドポイントサービス側に戻り、承認作業を行う。
スクリーンショット 2020-09-28 114931.png

4.動作確認

Client側のEC2でEC2 Instance Connectで接続し、エンドポイントにcurlで接続する。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0