やること
ローカルPCから、Publicサブネットに建てたEC2インスタンスを踏み台にして、Privateサブネット内のEC2インスタンスに直接アクセスする。
EC2インスタンスセットアップ
yamlファイル
以下yamlファイルをCloudFormationで作成する。
$ tree
.
├── ec2.yml
└── vpc.yml
vpc.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Lesson CloudFormation
Resources:
VPC:
# https://docs.aws.amazon.com/en_us/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
Tags:
- Key: Name
Value: Lesson VPC
PublicSubnet:
# https://docs.aws.amazon.com/en_us/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html
Type: AWS::EC2::Subnet
Properties:
CidrBlock: 10.0.0.0/24
# https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html
VpcId: !Ref VPC
# https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html
# https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getavailabilityzones.html
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-public-subnet
PrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: 10.0.1.0/24
VpcId: !Ref VPC
AvailabilityZone: !Select [ 0, !GetAZs ]
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-private-subnet
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Ref AWS::StackName
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref InternetGateway
VpcId: !Ref VPC
# 定義した時点で自分のVPC内へのルートがデフォルトで設定されている。そのためインターネットゲートウェイへのルートだけ追加すれば良い。
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-public-routetable
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub ${AWS::StackName}-private-routetable
RouteToInternetGateway:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet
RouteTableId: !Ref PublicRouteTable
PrivateSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet
RouteTableId: !Ref PrivateRouteTable
# https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html
Outputs:
VpcId:
Description: VPC ID
Value: !Ref VPC
Export:
Name: VpcId
PublicSubnet:
Description: PublicSubnet
Value: !Ref PublicSubnet
Export:
Name: PublicSubnet
PrivateSubnet:
Description: PrivateSubnet
Value: !Ref PrivateSubnet
Export:
Name: PrivateSubnet
ec2.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Lesson CloudFormation
Parameters:
EC2AMI:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
KeyName:
# CloudFormation実行時の引数にKeyNameにsshキーを指定すると値が入る
# https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-cli-creating-stack.html
Type: AWS::EC2::KeyPair::KeyName
Description: The EC2 Key Pair to allow SSH access to the instance
Resources:
SecurityGroupForPublicServer:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: !Sub ${AWS::StackName}-SecurityGroupForPublicServer
# https://qiita.com/tiibun/items/67aa74cdc17bc0b9812c
VpcId: !ImportValue VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
PublicServer:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref EC2AMI
InstanceType: t2.micro
# https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-iface-embedded.html#aws-properties-ec2-network-iface-embedded-deviceindex
NetworkInterfaces:
- SubnetId: !ImportValue PublicSubnet
GroupSet:
- !Ref SecurityGroupForPublicServer
AssociatePublicIpAddress: true
DeviceIndex: 0
Tags:
- Key: Name
Value: PublicServer
KeyName: !Ref KeyName
SecurityGroupForPrivateServer:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: !Sub ${AWS::StackName}-SecurityGroupForPrivateServer
VpcId: !ImportValue VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
SourceSecurityGroupId: !Ref SecurityGroupForPublicServer
PrivateServer:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref EC2AMI
InstanceType: t2.micro
NetworkInterfaces:
- SubnetId: !ImportValue PrivateSubnet
GroupSet:
- !Ref SecurityGroupForPrivateServer
DeviceIndex: 0
Tags:
- Key: Name
Value: PrivateServer
KeyName: !Ref KeyName
stack作成(EC2インスタンス作成)
以下、vpc作成コマンド
$ aws cloudformation validate-template --template-body file://vpc.yml
{
"Parameters": [],
"Description": "Lesson CloudFormation"
}
$ aws cloudformation create-stack --stack-name lesson-vpc --template-body file://vpc.yml
以下、ec2インスタンス作成コマンド
$ aws cloudformation validate-template --template-body file://ec2.yml
{
"Parameters": [
{
"ParameterKey": "KeyName",
"NoEcho": false,
"Description": "The EC2 Key Pair to allow SSH access to the instance"
},
{
"ParameterKey": "EC2AMI",
"DefaultValue": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2",
"NoEcho": false
}
],
"Description": "Lesson CloudFormation"
}
$ aws cloudformation create-stack --stack-name lesson-ec2 --template-body file://ec2.yml --parameters ParameterKey=KeyName,ParameterValue=MyKeyPair
多段SSH接続
以下のコマンドでAWSのsshキーペアを作成する。
$ aws ec2 create-key-pair --key-name MyKeyPair --query 'KeyMaterial' --output text > MyKeyPair.pem
$ chmod 400 MyKeyPair.pem
$ ll ~/.ssh/aws/
total 8
-r-------- 1 fukazawakeisuke staff 1675 8 27 11:40 MyKeyPair.pem
以下のように多段接続用にssh/configファイルを編集する。
それぞれのHostNameの値はAWSのコンソール画面から確認した値を入力した。
$ cat ~/.ssh/config
Host cfn-public-ec2
HostName 13.231.152.186
User ec2-user
Port 22
IdentityFile MyKeyPair.pem
Host cfn-private-ec2
HostName 10.0.1.162
User ec2-user
Port 22
IdentityFile MyKeyPair.pem
ProxyCommand ssh -W %h:%p cfn-public-ec2
以下の環境で
$ tree
.
└── MyKeyPair.pem
0 directories, 1 file
以下のコマンドを使って多段SSH接続した。
$ ssh cfn-private-ec2
[ec2-user@ip-10-0-1-162 ~]$
[ec2-user@ip-10-0-1-162 ~]$ hostname
ip-10-0-1-162.ap-northeast-1.compute.internal
Stackの削除(EC2削除)
以下のコマンドを実行すればok
※ec2のスタックから削除することに注意。
$ aws cloudformation delete-stack --stack-name lesson-ec2
$ aws cloudformation delete-stack --stack-name lesson-vpc