AWS system manager (SSM) enables vscode ssh remoting to an EC2 in a private subnet, or a public EC2 without opening port 22.
- Setup a connection to a private EC2 via SSM
- CloudWatch to stop EC2 after 30 minutes idle
- Setup vscode ssh remote to the EC2 via proxyCommand
- Create the infrastructure by a CDK stack
Architecture#
CDK stack#
create a VPC with a S3 VPC endpoint
const vpc = new aws_ec2.Vpc(this, 'VpcWithS3Endpoint', {gatewayEndpoints: {S3: {service: aws_ec2.GatewayVpcEndpointAwsService.S3}}})
add system manager VPC interface endpoint
vpc.addInterfaceEndpoint('VpcIterfaceEndpointSSM', {service: aws_ec2.InterfaceVpcEndpointAwsService.SSM})
create an IAM role for the EC2
const role = new aws_iam.Role(this, 'RoleForEc2ToAccessS3', {roleName: 'RoleForEc2ToAccessS3',assumedBy: new aws_iam.ServicePrincipal('ec2.amazonaws.com')})
role for EC2 to communicate with SSM
role.addManagedPolicy(aws_iam.ManagedPolicy.fromManagedPolicyArn(this,'PolicySSMMangerAccessS3','arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore'))
policy for EC2 to access S3
role.attachInlinePolicy(new aws_iam.Policy(this, 'PolicyForEc2AccessS3', {policyName: 'PolicyForEc2AccessS3',statements: [new aws_iam.PolicyStatement({actions: ['s3:*'],resources: ['*']})]}))
launch an EC2 in a private subnet
const ec2 = new aws_ec2.Instance(this, 'Ec2ConnectVpcEndpointS3', {role: role,keyName: 'hai_ec2_t4g_large',vpc: vpc,instanceName: 'Ec2ConnectVpcEndpointS3',instanceType: aws_ec2.InstanceType.of(aws_ec2.InstanceClass.T2,aws_ec2.InstanceSize.LARGE),machineImage: aws_ec2.MachineImage.latestAmazonLinux(),securityGroup: sg,vpcSubnets: {subnetType: aws_ec2.SubnetType.PRIVATE}})
Install ssm plugin for local#
follow this to install ssm plugin for the local machine
start a ssm session from the local machine
aws ssm start-session --target "EC2-INSTANCE-ID"
Configure ssh for local#
follow this to install ssh remote extension for vscode
generate SSH key pair from the local machine
ssh-keygen -b 4096 -C 'VS Code Remote SSH user' -t rsa
then copy and append the public key id_rsa.pub to ec2 ~/.ssh/authorized_keys
configure the ~/.ssh/config file
Host ssm-private-ec2IdentityFile ~/.ssh/id_rsaHostName i-026bb5f5caaf16aa1User ec2-userProxyCommand sh -c "~/.ssh/ssm-private-ec2-proxy.sh %h %p"
create a ssm-private-ec2-proxy.sh file
#!/bin/bashAWS_PROFILE=''AWS_REGION=''MAX_ITERATION=5SLEEP_DURATION=5# Arguments passed from SSH clientHOST=$1PORT=$2echo $HOST# Start ssm sessionaws ssm start-session --target $HOST \--document-name AWS-StartSSHSession \--parameters portNumber=${PORT} \--profile ${AWS_PROFILE} \--region ${AWS_REGION}
vscode will create a ssh connection to the EC2 via the ProxyCommand script which creates a SSM session under the hood. This is the way vscode ssh remote with cloud9 works
Configure vscode#
keep alive settings.json
{"remote.SSH.connectTimeout": 60}
Troubleshooting#
executable the ssh-proxy.ssh file
chmod +rwx ssh-proxy.sh
reset ssh server in ec2
sudo systemctl restart sshd.service