🧚♀️
[AWS]EC2にパブリック IPv4 アドレスがなくてセッションマネージャーは繋がらなかった件
こんにちは。深緑です。
先日CloudFormationでEC2インスタンスを起動+セッションマネージャーで接続可能なところまで持ってこうとしたのですがどハマりしたので原因を記しておきます。
書いたのはこのようなCloudFormationです。
VPCを作るCloudFormation
VPCを作るCloudFormation
training-vpc.yaml
Description:
Simple VPC
Parameters:
EnvironmentName:
Description: An environment name that is prefixed to resource names
Type: String
VpcCIDR:
Description: Please enter the IP range (CIDR notation) for this VPC
Type: String
Default: 10.192.0.0/16
PublicSubnet1CIDR:
Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
Type: String
Default: 10.192.10.0/24
PublicSubnet2CIDR:
Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
Type: String
Default: 10.192.11.0/24
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-vpc
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-igw
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: !Ref PublicSubnet1CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-public-subnet-1
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: !Select [1, !GetAZs ""]
CidrBlock: !Ref PublicSubnet2CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-public-subnet-2
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-public-routes
DefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet1
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet2
Outputs:
TrainingVPC:
Description: A reference to the created VPC
Value: !Ref VPC
Export:
Name: !Sub ${EnvironmentName}-vpc
TrainingPublicSubnets:
Description: A list of the public subnets
Value: !Join [",", [!Ref PublicSubnet1, !Ref PublicSubnet2]]
Export:
Name: !Sub ${EnvironmentName}-public-subnets
TrainingPublicSubnet1:
Description: A reference to the public subnet in the 1st Availability Zone
Value: !Ref PublicSubnet1
Export:
Name: !Sub ${EnvironmentName}-public-subnet1
TrainingPublicSubnet2:
Description: A reference to the public subnet in the 2nd Availability Zone
Value: !Ref PublicSubnet2
Export:
Name: !Sub ${EnvironmentName}-public-subnet2
EC2を作るCloudFormation
EC2を作るCloudFormation
training-ec2-web
Description:
Simple web server
Parameters:
EnvironmentName:
Description: An environment name that is prefixed to resource names
Type: String
KeyName:
Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
Type: AWS::EC2::KeyPair::KeyName
ConstraintDescription: must be the name of an existing EC2 KeyPair.
ImageId:
Description: AMI ID
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
InstanceType:
Description: WebServer EC2 instance type
Type: String
Default: t3.micro
AllowedValues:
- t3.micro
- t3.small
- t3.medium
ConstraintDescription: must be a valid EC2 instance type.
Resources:
WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub ${EnvironmentName}-sg-web
GroupDescription: Security group for web server
VpcId: !ImportValue
"Fn::Sub": "${EnvironmentName}-vpc"
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-sg-web
WebRole:
Type: AWS::IAM::Role
Properties:
Path: /
RoleName: !Sub ${EnvironmentName}-iamrole-web
Description: IAM Role for web server
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
MaxSessionDuration: 3600
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-iamrole-web
WebInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: /
Roles:
- !Ref WebRole
WebInstance1:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
IamInstanceProfile: !Ref WebInstanceProfile
KeyName: !Ref KeyName
ImageId: !Ref ImageId
NetworkInterfaces:
- SubnetId: !ImportValue
"Fn::Sub": "${EnvironmentName}-public-subnet1"
GroupSet:
- !Ref WebSecurityGroup
AssociatePublicIpAddress: false
DeviceIndex: "0"
UserData: !Base64
Fn::Sub: |
#cloud-config
repo_update: true
repo_upgrade: all
runcmd:
- yum install -y https://s3.region.amazonaws.com/amazon-ssm-region/latest/linux_amd64/amazon-ssm-agent.rpm
- systemctl enable amazon-ssm-agent
- systemctl start amazon-ssm-agent
Tags:
- Key: Name
Value: !Sub ${EnvironmentName}-ec2-web1
Outputs:
TrainingWebInstance1:
Description: A reference to the created web server instance
Value: !Ref WebInstance1
Export:
Name: !Sub ${EnvironmentName}-ec2-web1
TrainingWebSecurityGroup:
Description: A reference to the created security group for web server
Value: !Ref WebSecurityGroup
Export:
Name: !Sub ${EnvironmentName}-sg-web
セッションマネージャーに繋がらない
上記CloudFormationでVPCとEC2はできたのですが、
セッションマネージャーでインスタンスが選択肢に出てきませんでした。
ロールは正しいはずです。
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
UserDataでamazon-ssm-agentもインストール、起動できています。
UserData: !Base64
Fn::Sub: |
#cloud-config
repo_update: true
repo_upgrade: all
runcmd:
- yum install -y https://s3.region.amazonaws.com/amazon-ssm-region/latest/linux_amd64/amazon-ssm-agent.rpm
- systemctl enable amazon-ssm-agent
- systemctl start amazon-ssm-agent
しばらく悩んだところ、AssociatePublicIpAddress
をtrueにしたら繋がるようになりました。
AssociatePublicIpAddress: true
セッションマネージャーはパブリックIPで接続する?
AssociatePublicIpAddress
をtrueにしないと接続できないということは、
セッションマネージャーはパブリックIPで接続してるのかもしれませんね。
この観点で調べてみたところ、パブリックIPを持たせてないプライベートサブネットのEC2でも、NATゲートウェイを経由していれば接続できました。
NATゲートウェイはIPを持ってるからパブリックIPアドレスを持ってるのと同等なんですかね。
Discussion