AWS Systems ManagerでEC2にアクセスする構築ハンズオン


この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。

はじめに

何度プライベートサブネットにEC2 を構築しAWS Systems Manager(SSM)から接続する構築を行なったか覚えてもいませんが、毎回何処か抜けたり、十分な時間を待たずにSSMのフリートマネージャーを見ては「まだ反映されていない???何処か間違ったか、、、カタカタ、、、繋がらん、、、」など、個人的には憂鬱な作業だったので CFn テンプレート化して、これを流すだけでアクセスが出来る構築が出来るようにしてしまいます。


構成図


ハンズオン

構築のながれ

1.ネットワーク系 + エンドポイント系 + EC2系 テンプレート作成


1.ネットワーク系 + エンドポイント系 + EC2系 テンプレート作成

1.1.CloudFormation構築リソース一覧

主に構築されるAWSリソースの一覧を記載

1.1.1.ネットワーク系

VPCプライベートサブネットルートテーブルを作成

サービス名 その他
VPC 192.168.0.0/16 ※ デフォルトCIDR
PrivateSubnet 192.168.0.0/24 ※ デフォルトCIDR
PrivateRouteTable
1.1.2.エンドポイント系

エンドポイント3種類インターフェイス型 と それら3つにアタッチさせるSGの作成

サービス名 エンドポイントサービス名 その他
EndPoints com.amazonaws.[region].ec2messages インターフェイス型
EndPoints com.amazonaws.[region].ssm インターフェイス型
EndPoints com.amazonaws.[region].ssmmessages インターフェイス型
EndPoints SG IN : 192.168.0.0/16 からの 443 許可 / OUT : すべて許可
1.1.3.EC2系

SSMのフリートマネージャー からアクセスする先のEC2を作成

サービス名 その他
EC2 AMI : Windows_Server-2016-Japanese-Full-Base-2023.01.19
EC2 SG IN : 設定なし / OUT : すべて許可

1.2.CloudFormation テンプレート

AWSTemplateFormatVersion: "2010-09-09"
Description:
  Create NetWork EC2 SSM
# ------------------------------------------------------------#
#  Metadata
# ------------------------------------------------------------#
Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: "VPC Configuration"
        Parameters:
          - Name
          - VPCCIDR
          - PrivateSubnetCIDR
      - Label:
          default: "EC2 Configuration"
        Parameters:
          - AMIId
          - InstanceType
          - KeyPair
      - Label:
          default: "Tags"
        Parameters:
          - UserName
# ------------------------------------------------------------#
#  InputParameters
# ------------------------------------------------------------#
Parameters:
  Name:
    Type: String
    Default: 【リソース名】

  VPCCIDR:
    Type: String
    Default: 192.168.0.0/16

  PrivateSubnetCIDR:
    Type: String
    Default: 192.168.0.0/24

  AMIId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-windows-latest/Windows_Server-2016-Japanese-Full-Base

  InstanceType:
    Type: String
    Default: t2.micro

  KeyPair:
    Type: String
    Default: 【自身のキーペア】

  UserName:
    Type: String
    Default: 【タグを利用する場合記入】

# ------------------------------------------------------------#
#  Resources
# ------------------------------------------------------------#
Resources:
# ------------------------------------------------------------#
#  VPC
# ------------------------------------------------------------#
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VPCCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub ${Name}-VPC
        - Key: User
          Value: !Ref UserName
# ------------------------------------------------------------#
#  Subnet
# ------------------------------------------------------------#
  PrivateSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Select [0, !GetAZs ""]
      CidrBlock: !Ref PrivateSubnetCIDR
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${Name}-PrivateSubnet
        - Key: User
          Value: !Ref UserName
# ------------------------------------------------------------#
#  RouteTable
# ------------------------------------------------------------#
  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${Name}-PrivateRouteTable
        - Key: User
          Value: !Ref UserName

  PrivateSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet
      RouteTableId: !Ref PrivateRouteTable
# ------------------------------------------------------------#
#  Endpoint
# ------------------------------------------------------------#
  EndpointSSM:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      PrivateDnsEnabled: true
      SecurityGroupIds:
        - !Ref EndpointSecurityGroup
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
      SubnetIds:
        - !Ref PrivateSubnet
      VpcEndpointType: Interface
      VpcId: !Ref VPC

  EndpointSSMMessages:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      PrivateDnsEnabled: true
      SecurityGroupIds:
        - !Ref EndpointSecurityGroup
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
      SubnetIds:
        - !Ref PrivateSubnet
      VpcEndpointType: Interface
      VpcId: !Ref VPC

  EndpointEC2Messages:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      PrivateDnsEnabled: true
      SecurityGroupIds:
        - !Ref EndpointSecurityGroup
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
      SubnetIds:
        - !Ref PrivateSubnet
      VpcEndpointType: Interface
      VpcId: !Ref VPC
# ------------------------------------------------------------#
#  Endpoint SG
# ------------------------------------------------------------#
  EndpointSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: EndpointSecurityGroup
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${Name}-EndpointSecurityGroup
        - Key: User
          Value: !Ref UserName
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: !Ref VPCCIDR

# ------------------------------------------------------------#
#  EC2
# ------------------------------------------------------------#
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref InstanceType
      SubnetId: !Ref PrivateSubnet
      ImageId: !Ref AMIId
      SecurityGroupIds:
        - !Ref EC2SecurityGroup
      IamInstanceProfile: !Ref EC2InstanceProfile
      KeyName: !Ref KeyPair
      Tags:
        - Key: Name
          Value: !Sub ${Name}-EC2Instance
        - Key: User
          Value: !Ref UserName
# ------------------------------------------------------------#
#  EC2 Role
# ------------------------------------------------------------#
  EC2IAMRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Sub ${Name}-SSM-role
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

  EC2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - Ref: EC2IAMRole
      InstanceProfileName: !Sub ${Name}-EC2InstanceProfile
# ------------------------------------------------------------#
#  EC2 SG
# ------------------------------------------------------------#
  EC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: EC2SecurityGroup
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${Name}-EC2SecurityGroup
        - Key: User
          Value: !Ref UserName
# ------------------------------------------------------------#
#  Outputs
# ------------------------------------------------------------#
Outputs:
  VPC:
    Value: !Ref VPC
    Export:
      Name: !Sub ${Name}-VPC

  VPCCIDR:
    Value: !Ref VPCCIDR
    Export:
      Name: !Sub ${Name}-VPCCIDR

  PrivateSubnet:
    Value: !Ref PrivateSubnet
    Export:
      Name: !Sub ${Name}-PrivateSubnet

  EndpointSSM:
    Value: !Ref EndpointSSM
    Export:
      Name: !Sub ${Name}-EndpointSSM

  EndpointSSMMessages:
    Value: !Ref EndpointSSMMessages
    Export:
      Name: !Sub ${Name}-EndpointSSMMessages

  EndpointEC2Messages:
    Value: !Ref EndpointEC2Messages
    Export:
      Name: !Sub ${Name}-EndpointEC2Messages

  EC2Instance:
    Value: !Ref EC2Instance
    Export:
      Name: !Sub ${Name}-EC2Instance

挙動の確認

① AWS SystemsManager(SSM)からフリートマネージャーを押下

②『ノードアクション』より『リモートデスクトップ(RDP)との接続』を押下

③『キーペア』を選択して、自身のキーペアを参照し『Connect』を押下

④EC2(Windows)にアクセスすることができる


さいごに

もうこれで、ほぼ間違えず構築が出来るという方法を手にいれることが出来ました。
今までの必ずと言っていいほど毎回検索 → スクラッチ → 繋がらない → ポリシー、SG、etc、、、何か抜け漏れ? の循環から、やっと抜け出せそうです。

Last modified: 2023-03-23

Author