VSCodeのRemoteSSH機能からEC2へ接続するのにEC2 Instance Connect Endpointを使用してみたのでその時の設定をブログに残します。
やること
プライベートサブネットで起動したEC2へEC2 Instance Connect Endpoint経由でSSH接続ができる環境を作成します。
最後にVSCodeのRemoteSSHから接続する設定を行い接続の確認を行います。
AWSの構成は以下の通りです。
AWSリソースの作成
AWSリソースの作成は以下のCloudFormationテンプレートを使用しました。
AWSTemplateFormatVersion: "2010-09-09"
Description: EC2 Instance Connect Endpoint Test Stack
Metadata:
# ------------------------------------------------------------#
# Metadata
# ------------------------------------------------------------#
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Parameters for VPC
Parameters:
- VPCCIDR
- Label:
default: Parameters for Subnet
Parameters:
- PrivateSubnet01CIDR
- Label:
default: Parameters for ec2
Parameters:
- EC2VolumeSize
- EC2VolumeIOPS
- EC2AMI
- EC2InstanceType
- EC2Keypair
Parameters:
# ------------------------------------------------------------#
# Parameters
# ------------------------------------------------------------#
VPCCIDR:
Default: 172.30.0.0/16
Type: String
PrivateSubnet01CIDR:
Default: 172.30.1.0/24
Type: String
EC2VolumeSize:
Default: 32
Type: Number
EC2VolumeIOPS:
Default: 3000
Type: Number
EC2AMI:
Default: ami-05a03e6058638183d
Type: AWS::EC2::Image::Id
EC2InstanceType:
Default: t3.micro
Type: String
EC2Keypair:
Type: String
Resources:
# ------------------------------------------------------------#
# VPC
# ------------------------------------------------------------#
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: test-vpc
# ------------------------------------------------------------#
# Subnet
# ------------------------------------------------------------#
PrivateSubnet01:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: ap-northeast-1a
CidrBlock: !Ref PrivateSubnet01CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub test-private-subnet-01
VpcId: !Ref VPC
# ------------------------------------------------------------#
# Security Group
# ------------------------------------------------------------#
EicESG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: for EC2 Instance Connect Endpoint
GroupName: test-sg-eice
Tags:
- Key: Name
Value: test-sg-eice
VpcId: !Ref VPC
EC2SG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: for ec2
GroupName: test-sg-ec2
SecurityGroupIngress:
- FromPort: 22
IpProtocol: tcp
SourceSecurityGroupId: !Ref EicESG
ToPort: 22
Tags:
- Key: Name
Value: test-sg-ec2
VpcId: !Ref VPC
# ------------------------------------------------------------#
# EC2 Instance Connect Endpoint
# ------------------------------------------------------------#
EicE:
Type: "AWS::EC2::InstanceConnectEndpoint"
Properties:
SecurityGroupIds:
- !Ref EicESG
SubnetId: !Ref PrivateSubnet01
# ------------------------------------------------------------#
# EC2
# ------------------------------------------------------------#
EC2:
Type: AWS::EC2::Instance
Properties:
BlockDeviceMappings:
- DeviceName: /dev/xvda
Ebs:
DeleteOnTermination: true
Encrypted: true
Iops: !Ref EC2VolumeIOPS
VolumeSize: !Ref EC2VolumeSize
VolumeType: gp3
DisableApiTermination: false
ImageId: !Ref EC2AMI
InstanceType: !Ref EC2InstanceType
KeyName: !Ref EC2Keypair
NetworkInterfaces:
- DeleteOnTermination: true
DeviceIndex: 0
GroupSet:
- !Ref EC2SG
SubnetId: !Ref PrivateSubnet01
Tags:
- Key: Name
Value: test-ec2-web
EC2のキーペアは作成済みのものを使用します。
EC2のAMIはAmazon Linux2023を使用しています。
EC2に設定するセキュリティグループではEC2 Instance Connect EndpointからのSSHアクセスを許可するようにインバウンドルールでSSHを許可するようにしています。
118行目から123行目の設定でEC2 Instance Connect Endpointを作成します。
AWS::EC2::InstanceConnectEndpoint
デプロイは以下のコマンドを実行します。
aws cloudformation create-stack --stack-name CloudFormationスタック名 --template-body file://CloudFormationテンプレートファイル名 --parameters ParameterKey=EC2Keypair,ParameterValue=キーペアの名前
デプロイが完了したら以下のコマンドでローカルから接続できるか確認します。
ssh -i キーペア名.pem ec2-user@EC2インスタンスID -o ProxyCommand='aws ec2-instance-connect open-tunnel --instance-id EC2インスタンスID'
ローカルから接続するためには以下のドキュメントに記載されているIAMポリシーが設定されたIAMユーザーからアクセスキーを発行して「aws configure」コマンドなどで設定を行ってください。
ユーザーに EC2 Instance Connect Endpoint を使用したインスタンスへの接続を許可
今回は検証用なので"Condition"は削除したポリシーにしました。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EC2InstanceConnect",
"Action": "ec2-instance-connect:OpenTunnel",
"Effect": "Allow",
"Resource": "*"
},
{
"Sid": "SSHPublicKey",
"Effect": "Allow",
"Action": "ec2-instance-connect:SendSSHPublicKey",
"Resource": "*"
},
{
"Sid": "Describe",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeInstanceConnectEndpoints"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
アクセスキーの設定は以下のドキュメントを参考に設定してください。
設定ファイルと認証情報ファイルの設定
接続が成功すると以下のようにAmazon Linux2023のシェルが確認できます。
, #_
~\_ ####_ Amazon Linux 2023
~~ \_#####\
~~ \###|
~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023
~~ V~' '->
~~~ /
~~._. _/
_/ _/
_/m/'
Last login: Wed Jan 31 13:48:46 2024 from 172.30.1.245
[ec2-user@ip-172-30-1-68 ~]$
VSCodeの設定
接続まで確認ができたら「~/.ssh/config」に以下の設定を行います。
Host test-ec2
HostName EC2インスタンスID
User ec2-user
IdentityFile .\キーペア名.pem
ProxyCommand aws ec2-instance-connect open-tunnel --instance-id EC2インスタンスID
VSCodeにRemoteSSHの拡張機能を追加します。
VSCodeの拡張機能でRemoteSSHを検索してインストールしてください。
インストールができたらVSCodeのリモートエクスプローラーからtest-ec2を選択して接続します。
接続に成功すると以下の画像のように「ec2-user」のディレクトリを表示することができます。
さいごに
以下のブログのようにSystems ManagerのSession ManagerでもVSCodeからRemoteSSHでEC2に接続することが可能です。
接続元の端末にSession Manager Pluginを導入している場合はこちらの方法での接続でもよいと思います。
AWS Systems Manager と VS Code Remote SSH を組み合わせて快適なリモート開発環境を作る方法