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での実装の参考になれば幸いです。
