🔒
PrivateEC2 + EC2 Instance Connect EndpointをCDKで構築
はじめに
諸事情でネットワークから切り離したEC2を用意する必要があり、マネジメントコンソールから用意するのは面倒だったためCDKで作成したので備忘録として残します。
EC2 Instance Connect Endpointとは
PrivateSubnetに配置したEC2に鍵設定なしでマネジメントコンソールからアクセスできる仕組み。PublicIpv4(お金かかるようになりますし…)も不要、踏み台も不要なので簡単な操作なら非常に役立ちます。
ソースコード
スタック全体
import { Stack, StackProps } from "aws-cdk-lib";
import {
CfnInstanceConnectEndpoint,
Instance,
InstanceClass,
InstanceSize,
InstanceType,
MachineImage,
Port,
SecurityGroup,
SubnetType,
Vpc,
} from "aws-cdk-lib/aws-ec2";
import { Construct } from "constructs";
export class Ec2EicStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// VPC
const vpc = new Vpc(this, "VPC", {
maxAzs: 1,
subnetConfiguration: [
{
name: "private",
subnetType: SubnetType.PRIVATE_ISOLATED,
},
],
});
// SecurityGroup
const instanceSG = new SecurityGroup(this, "InstanceSG", {
vpc,
});
const eicSG = new SecurityGroup(this, "EICSG", {
vpc,
allowAllOutbound: false,
});
instanceSG.addIngressRule(eicSG, Port.tcp(22));
eicSG.addEgressRule(instanceSG, Port.tcp(22));
// EC2Instance
new Instance(this, "Instance", {
vpc,
instanceType: InstanceType.of(InstanceClass.T2, InstanceSize.MICRO),
machineImage: MachineImage.latestAmazonLinux2023(),
securityGroup: instanceSG,
});
// EC2EIP
new CfnInstanceConnectEndpoint(this, "EIP", {
subnetId: vpc.selectSubnets({ subnetType: SubnetType.PRIVATE_ISOLATED }).subnetIds[0],
securityGroupIds: [eicSG.securityGroupId],
});
}
}
VPC
VPCには今回プライベートのみ用意します。
const vpc = new Vpc(this, "VPC", {
maxAzs: 1,
subnetConfiguration: [
{
name: "private",
subnetType: SubnetType.PRIVATE_ISOLATED,
},
],
});
Security Group
EC2とEndpointが疎通できるようにセキュリティグループを設定します。
// SecurityGroup
const instanceSG = new SecurityGroup(this, "InstanceSG", {
vpc,
});
const eicSG = new SecurityGroup(this, "EICSG", {
vpc,
allowAllOutbound: false,
});
instanceSG.addIngressRule(eicSG, Port.tcp(22));
eicSG.addEgressRule(instanceSG, Port.tcp(22));
EC2 Connect Instance Endpoint
EC2 Connect Instance EndpointはL1で提供してくれているのでそちらを使います。
new CfnInstanceConnectEndpoint(this, "EIP", {
subnetId: vpc.selectSubnets({ subnetType: SubnetType.PRIVATE_ISOLATED }).subnetIds[0],
securityGroupIds: [eicSG.securityGroupId],
});
マネジメントコンソールで確認
デプロイが完了したら、AWSマネジメントコンソールを開いて確認していきます。
VPC
PrivateSubnetがあり、ルートテーブルが存在しないVPCを確認。(外部への接続がない状態)
EC2
プライベートサブネットに配置されたEC2が起動されていることを確認。
VPCエンドポイント
EC2 Instance Connect Endpointが作成されていることを確認。
接続確認
作成されたEC2から接続を試みます。
EC2 Instance Connect エンドポイントを使用して接続する
を選択してエンドポイントを指定します。作成したエンドポイントが表示されることを確認し選択します。
接続を試みてシェルが立ち上がれば成功です。
まとめ
踏み台の用意や、鍵を用意してグローバルIPを調べて絞るなど昔はやること多かったのですが、非常に楽になりました。ただ、マネジメントコンソールからのみとなるのでマクロを実行したい場合などは今まで通りの手順は必要そうです。
とはいえ簡単な確認作業とかなら便利なので今後も機会があれば使っていこうと思います。
Discussion
実は OpenSSH コマンドなどで EC2 Instance Connect Endpoint を利用する方法があります。
公式ドキュメントにも記載されていて、要は以下のような ssh config を設定すると接続できます。
この情報がお役に立てば何よりです!