前回EC2を立ち上げたが、このEC2への接続手段はまだ用意しなかった。
ssh接続するためにポート開放、鍵作成を行うのが標準的な方法かもしれないが
せっかくなのでSession Manager経由で接続できるようにしたい。
Session Managerを使うと、IAMユーザー単位で接続ユーザーの認可ができるため
セキュアであるし、セキュリティ上の管理が楽になる。
一方SSHでは鍵管理を別途行う必要があるし、鍵をどこかに保管しておくといった行為は
CDK等IaCでEC2の作成・削除を繰り返すこととの相性が良くない。
せっかくIaCでステートレスなインフラ管理の夢を描いているのに、鍵を失えないという煩雑な要素が残ってしまう。
関連資料
-
セッションマネージャーを使って鍵ストレスの無いEC2アクセス! | DevelopersIO
- 画面上での操作を参考にして、必要なCDK上のリソースを見積もって作っていく。
前提
- aws cdkでEC2を起動している
- AWS CDKでVPCを作りEC2を立ち上げる #vpc - Qiita
- ここでEC2を立ち上げるためのaws cdkのコードがあるので、ここへ追記していく
- session manager pluginがインストールしてある
brew install --cask session-manager-plugin
$ session-manager-plugin --version
1.2.633.0
SSMエージェントインストール(はしなくていい)
今回選択したAMIのamazonlinux2023には元からssm agentが入ってるはず。
他のOSだとインストール要。
IAMロールの作成・session managerのためのポリシーを追加
そもそもCDKではデフォルトでIAMロールが作成されている。
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Instance.html#role
どんなデフォルトのIAMロールが作成されているか、確認してみる。
$ cdk synth | grep -A 14 InstanceRole.\*:
SampleCdkEc2NginxInstanceInstanceRole7F91D057:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: sts:AssumeRole
Effect: Allow
Principal:
Service: ec2.amazonaws.com
Version: "2012-10-17"
Tags:
- Key: Name
Value: SampleCdkEc2NginxStack/SampleCdkEc2NginxInstance
Metadata:
aws:cdk:path: SampleCdkEc2NginxStack/SampleCdkEc2NginxInstance/InstanceRole/Resource
といった感じ。
EC2インスタンスがこのIAMロールをAssumeすることができる、というだけのロールで特に権限は与えられていない。
これを代替する形でIAMロールを作成してアタッチする。
IAMロール作成
//IAM Role
const role = new iam.Role(this, "SampleCdkEc2NginxRole", {
assumedBy: new iam.ServicePrincipal("ec2.amazonaws.com"),
});
// allow using sesson manager
role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore"));
EC2インスタンスにアタッチ
const instance = new ec2.Instance(this, "SampleCdkEc2NginxInstance", {
vpc,
instanceType: new ec2.InstanceType("t3a.micro"),
machineImage: ec2.MachineImage.latestAmazonLinux2023(),
role: role, // 追加
});
作成予定のリソースを確認する
$ cdk diff
# 略
Resources
[+] AWS::EC2::VPC SampleCdkEc2NginxVpc SampleCdkEc2NginxVpc79B44740
[+] AWS::EC2::Subnet SampleCdkEc2NginxVpc/publicSubnet1/Subnet SampleCdkEc2NginxVpcpublicSubnet1SubnetC6BE7495
[+] AWS::EC2::RouteTable SampleCdkEc2NginxVpc/publicSubnet1/RouteTable SampleCdkEc2NginxVpcpublicSubnet1RouteTable69E390ED
[+] AWS::EC2::SubnetRouteTableAssociation SampleCdkEc2NginxVpc/publicSubnet1/RouteTableAssociation SampleCdkEc2NginxVpcpublicSubnet1RouteTableAssociation64BFC4A8
[+] AWS::EC2::Route SampleCdkEc2NginxVpc/publicSubnet1/DefaultRoute SampleCdkEc2NginxVpcpublicSubnet1DefaultRoute7AA3AF5C
[+] AWS::EC2::InternetGateway SampleCdkEc2NginxVpc/IGW SampleCdkEc2NginxVpcIGWE2F2A3CC
[+] AWS::EC2::VPCGatewayAttachment SampleCdkEc2NginxVpc/VPCGW SampleCdkEc2NginxVpcVPCGWA41DCC75
[+] Custom::VpcRestrictDefaultSG SampleCdkEc2NginxVpc/RestrictDefaultSecurityGroupCustomResource SampleCdkEc2NginxVpcRestrictDefaultSecurityGroupCustomResource337ECAE3
[+] AWS::IAM::Role Custom::VpcRestrictDefaultSGCustomResourceProvider/Role CustomVpcRestrictDefaultSGCustomResourceProviderRole26592FE0
[+] AWS::Lambda::Function Custom::VpcRestrictDefaultSGCustomResourceProvider/Handler CustomVpcRestrictDefaultSGCustomResourceProviderHandlerDC833E5E
[+] AWS::IAM::Role SampleCdkEc2NginxRole SampleCdkEc2NginxRoleE5BA6A17
[+] AWS::EC2::SecurityGroup SampleCdkEc2NginxInstance/InstanceSecurityGroup SampleCdkEc2NginxInstanceInstanceSecurityGroup0DD5BDE2
[+] AWS::IAM::InstanceProfile SampleCdkEc2NginxInstance/InstanceProfile SampleCdkEc2NginxInstanceInstanceProfile2CB6865B
[+] AWS::EC2::Instance SampleCdkEc2NginxInstance SampleCdkEc2NginxInstance262C66EB
想定通り、[+] AWS::IAM::Role SampleCdkEc2NginxRole SampleCdkEc2NginxRoleE5BA6A17
が追加されている
session managerで接続してみる
# インスタンスIDを取得
$ aws ec2 describe-instances --query 'Reservations[].Instances[].[InstanceId,State.Name]' --output text
# i-0562c7fbf3f2308f4 running
# session managerで接続
$ aws ssm start-session --target i-0562c7fbf3f2308f4
Starting session with SessionId: xxxxx-nqy4g3pcpr7ejki54hb6ksrgum
# 以降はEC2の上での操作
sh-5.2$ whoami
ssm-user # ssm-userとして入っている
sh-5.2$ sudo su - ec2-user # 普段ec2に入って触っている使うユーザーへ切り替え
Last failed login: Sat Jun 22 12:10:15 UTC 2024 on pts/0
There was 1 failed login attempt since the last successful login.
[ec2-user@ip-10-0-0-81 ~]$ whoami
ec2-user # ec2-userとして入れた
[ec2-user@ip-10-0-0-81 ~]$ sudo -s
[root@ip-10-0-0-81 ec2-user]# whoami
root # rootになれた
これで、普段EC2にSSHして入るところをsession managerで入れるようになった。
(おまけ)後始末
実験終えれたので削除しておく。
$ cdk destroy
Are you sure you want to delete: SampleCdkEc2NginxStack (y/n)? y
SampleCdkEc2NginxStack: destroying... [1/1]
✅ SampleCdkEc2NginxStack: destroyed
まとめ
session manager経由でEC2のシェルに入ることができた。