- 公開日
- 最終更新日
【CloudFormation】CloudFormationで作成したキーペアをローカルに保存
この記事を共有する
目次
はじめに
サービスGの森です。
今回はCloudFormationテンプレートでデプロイしたキーペアを保存する方法について紹介します。
やりたいこと
CloudFormationで構築したキーペアは通常ローカルに保存されません。
...が、パラメータストアに「ec2/keypair/<キーペアのID>」というパラメータ名で自動的に保存されます。

そこで、このパラメータの値を取得して「秘密鍵(.pem)ファイル」を取得するスクリプトを作成してみます。
やってみた
1. テンプレートとスクリプトの作成
1. まずはEC2とキーペア用のテンプレートを作成します(VPCとサブネットはデフォルトのものを使用する為、IDはDefault値を未指定とします)
ec2.yml
#--------------------------------------------------#
# EC2 & KeyPair
#--------------------------------------------------#
AWSTemplateFormatVersion: 2010-09-09
Description: EC2 & KeyPair Template
#--------------------------------------------------#
# Parameters
#--------------------------------------------------#
Parameters:
# EC2用のAMI
AmiId:
Description: AMI ID of the EC2 Instance
Type: AWS::SSM::Parameter::Value
# デフォルトのVPC
VpcId:
Description: ID of VPC
Type: String
# デフォルトのサブネット
SubnetId:
Description: ID of Subnet
Type: String
#--------------------------------------------------#
# Resources
#--------------------------------------------------#
Resources:
# キーペア
KeyPair:
Type: AWS::EC2::KeyPair
Properties:
KeyFormat: pem
KeyName: my-keypair
KeyType: rsa
Tags:
- Key: Name
Value: my-keypair
# セキュリティグループ
Sg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: ec2-sg
GroupDescription: Allow SSH
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
# EC2インスタンス
Ec2:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: !Ref AmiId
KeyName: !Ref KeyPair
SubnetId: !Ref SubnetId
SecurityGroupIds:
- !Ref Sg
Tags:
- Key: Name
Value: my-instance
#--------------------------------------------------#
# Outputs
#--------------------------------------------------#
Outputs:
# キーペアID
KeyPairId:
Description: ID of the key pair
Value: !GetAtt KeyPair.KeyPairId
2. 次にキーペア保存用のスクリプトを作成します
install-key.sh
#!/bin/bash
# 引数を取得
STACK_NAME=$1
OUTPUT_NAME=$2
# 引数チェック
if [ -z "$STACK_NAME" ] || [ -z "$OUTPUT_NAME" ]; then
echo "エラー: 引数が不足しています"
exit 1
fi
# キーIDを取得
KEY_ID=$(aws cloudformation describe-stacks \
--stack-name $STACK_NAME \
--query "Stacks[0].Outputs[?OutputKey=='$OUTPUT_NAME'].OutputValue" \
--output text)
# キー名を取得
KEY_NAME=$(aws ec2 describe-key-pairs \
--key-pair-ids $KEY_ID \
--query "KeyPairs[0].KeyName" \
--output text)
# .pemファイルでキーを保存
aws ssm get-parameter \
--name "/ec2/keypair/$KEY_ID" \
--with-decryption \
--query "Parameter.Value" \
--output text > $KEY_NAME.pem
echo "キーを保存しました"
スクリプトについて
- 第一引数からスタック名、第二引数からOutput名を取得し、以下の処理を実行します
- CloudFormationスタックからキーペアID(Output値)を取得
- 取得したキーペアIDからキーペア名を取得
- パラメータストアから、キーペアIDに対応する秘密鍵を取得
- 取得した秘密鍵を「<キーペア名>.pem」として保存
2. 検証
1. Parameterをオーバーライドしてテンプレートをデプロイします
aws cloudformation deploy \
--stack-name ec2-stack \
--template-file ec2.yml \
--parameter-overrides AmiId=<任意のAMIのID> \
VpcId=<デフォルトVPCのID> \
SubnetId=<デフォルトサブネットのID>
2. 秘密鍵を取得するスクリプトを実行します
# スクリプトに実行権限を付与 chmod +x install-key.sh # 秘密鍵を取得するスクリプトを実行(スタック名: ec2-stack, Output名: KeyPairId) ./install-key.sh ec2-stack KeyPairId
3. ローカルに秘密鍵(.pem)ファイルが保存されました!

4. ユーザーに.pemファイルの実行権限を付与して、今回作成したEC2に接続してみます
# ユーザーに秘密鍵の読み取り権限のみ付与 chmod 400 my-keypair.pem # SSH接続 ssh -i <秘密鍵のパス> <接続先EC2インスタンスのIPアドレス>
5. スクリプトから作成した秘密鍵ファイルでEC2に接続できました!

おわりに
- 今回スクリプトを作成しましたが、組み込みの機能でこんなのあると便利だなと思いました(S3バケットを指定して保存とか)。
- CI/CDに組み込むと便利かなと思います。
この記事は私が書きました
森 翔吾
記事一覧最近はコンテナ・サーバレスを学習しています。 よろしくお願いします。