AWS CDKを使ってEC2インスタンスを構築する際、SSH接続用のKeyPair(キーペア)の指定・管理は避けて通れません。
今回は、CDKでよく使われる3つのKeyPair指定方法を、実際のTypeScriptコード例とともに解説していきたいと思います!
KeyPairとは?
KeyPairは、EC2インスタンスへSSHログインするための「公開鍵・秘密鍵ペア」です。AWSではKeyPairを事前に作成し、インスタンス起動時に指定することで、セキュアなアクセスを実現します。
やってみよう
1. 既存KeyPairのimport
すでにAWS上に作成済みのKeyPairをCDKで利用する場合は、fromKeyPairNameを使います。
メリット:既存運用との親和性が高く、最も一般的な方法です。
class KeyPair (construct) · AWS CDK
// 1. 既存KeyPairのimport // すでにAWS上に存在するKeyPair名('my-keypair')をCDKでインポートして利用 const importedKeyPair = ec2.KeyPair.fromKeyPairName(this, 'ImportedKeyPair', 'my-keypair'); new ec2.Instance(this, 'InstanceWithImportedKeyPair', { vpc: vpc, instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO), machineImage: ec2.MachineImage.latestAmazonLinux2(), keyName: importedKeyPair.keyPairName, });
2. keyNameを直指定
KeyPair名を直接文字列で指定する方法です。
メリット:シンプルで分かりやすいですが、KeyPairの存在チェックはCDK側で行われません。
この方法でデプロイすると次のメジャーバージョンで無くなるので1の方法に置き換えるよう警告が出ます。
なので、この方法は非推奨の実装となります。
class Instance (construct) · AWS CDK
[WARNING] aws-cdk-lib.aws_ec2.InstanceProps#keyName is deprecated.
- Use `keyPair` instead - https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2-readme.html#using-an-existing-ec2-key-pair
// 2. keyNameを直指定 // EC2インスタンス作成時にKeyPair名('my-keypair')を直接指定 new ec2.Instance(this, 'InstanceWithDirectKeyName', { vpc: vpc, instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO), machineImage: ec2.MachineImage.latestAmazonLinux2(), keyName: 'my-keypair', });
3. CfnKeyPairで新規作成&パラメータストア連携
CDKのL1コンストラクトのec2.CfnKeyPairを使うと、CloudFormation経由でKeyPairを新規作成できます。
注意点:CfnKeyPairで作成したKeyPairは秘密鍵が取得できません。AWSの仕様上、公開鍵のみがAWSに登録され、秘密鍵は生成・保存されません。そのため、SSH接続には利用できず、CI/CDの署名や一時的な検証用途など、秘密鍵が不要なケース向けです。
ですが、KeyPair名はパラメータストア(SSM)やSecretsManagerに保存しておくと、他リソースや運用時に参照しやすくなります。今回はパラメータストアでの実装を下記例として記述します。
class CfnKeyPair (construct) · AWS CDK
// 3. CfnKeyPairでCloudFormationリソース作成し、パラメータストアに保存 // CloudFormationで新規KeyPair('cfn-keypair')を作成 const cfnKeyPair = new ec2.CfnKeyPair(this, 'CfnKeyPair', { keyName: 'cfn-keypair', }); // 作成したKeyPair名をSSMパラメータストアに保存 new ssm.StringParameter(this, 'CfnKeyPairNameParameter', { parameterName: '/ec2/keypair/cfn-keypair/name', stringValue: cfnKeyPair.keyName as string, }); // SSMに保存したKeyPair名を利用してEC2インスタンスを作成 new ec2.Instance(this, 'InstanceWithCfnKeyPair', { vpc: vpc, instanceType: ec2.InstanceType.of(ec2.InstanceClass.T3, ec2.InstanceSize.MICRO), machineImage: ec2.MachineImage.latestAmazonLinux2(), keyName: cfnKeyPair.keyName, });
まとめ
- 既存KeyPairのimport … 既存運用との親和性が高く、CDKでの推奨方法。
keyPair
プロパティを使うことで将来的な非推奨にも対応できます。 - keyName直指定 … 実装はシンプルですが、
keyName
プロパティは非推奨となっており、デプロイ時に警告が出ます。存在チェックも行われません。 - CfnKeyPair新規作成 … CloudFormationでKeyPairを新規作成できますが、秘密鍵は取得できません。KeyPair名はSSMパラメータストアで管理するのが推奨です。
要件や運用方針に応じて、最適なKeyPair管理方法を選択しましょう!
以上、CDKでの実装の参考になれば幸いです。