我们能否通过 AWS Cloudformation 动态创建密钥对并将 .PEM 文件复制到 EC2 Linux 实例
Posted
技术标签:
【中文标题】我们能否通过 AWS Cloudformation 动态创建密钥对并将 .PEM 文件复制到 EC2 Linux 实例【英文标题】:Can we dynamically create Keypair through AWS Cloudformation and copy the .PEM file to EC2 Linux instance 【发布时间】:2020-05-16 00:32:27 【问题描述】:我的要求是创建一个 EC2 实例,该实例将从相同的 Cloudformation 模板动态创建密钥对。截至目前,我正在从 AWS 控制台创建密钥对,并通过 Cloudformation 将其分配给 EC2 实例,方法是从用户。
我查看了 AWS 文档,发现 KeyPair 可以从 AWS 控制台创建。
无论如何可以通过它从 Cloudformation 创建密钥对并将 .PEM 文件复制到实例中。
【问题讨论】:
【参考方案1】:这是关于私钥管理的。
EC2 密钥对有两个组件。公立和私立。公钥是 AWS 在创建实例时存储并推送到实例的内容。私钥永远不会存储在 AWS。在您使用控制台或通过 CLI 创建密钥对的那一刻 - 您有一个也是唯一的机会将其存储在您的机器上。
Cloud Formation 无法将私钥存储在您的机器上作为堆栈初始化的一部分。
您可以在这里考虑两步法:
1) 创建密钥或从您的计算机导入密钥。无论哪种方式,只有您可以访问私钥部分。
aws ec2 import-key-pair
or
aws ec2 create-key-pair
2) 在 cloudformation 中使用这个新创建的密钥。
SshKeyParameter:
Description: SSH Keypair to login to the instance
Type: AWS::EC2::KeyPair::KeyName
...
KeyName: !Ref SshKeyParameter
【讨论】:
在 AWS 中是否有我可以安全保存 .PEM 文件的地方,并且在从 cloudformation 创建 EC2 实例时,我可以在 EC2 机器中下载该文件。 理论上,您可以使用 ssh-keygen 生成密钥的实例/容器创建嵌套模板,向 AWS EC2 注册该密钥,将私有密钥保存在 AWS Secrets 中并返回密钥名称作为模板输出。但这似乎太麻烦了,而且无论如何都可能违反安全最佳实践。【参考方案2】:安东的回答是正确的。 但是,也有使用其他工具的替代方法。通常它们允许自动导入公钥。
Ansible:https://docs.ansible.com/ansible/latest/collections/amazon/aws/ec2_key_module.html#ansible-collections-amazon-aws-ec2-key-module
地形:https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/key_pair
甚至:https://binx.io/blog/2017/10/25/deploying-private-key-pairs-with-aws-cloudformation/
【讨论】:
【参考方案3】:按照安东的回答,它的工作正常。编写的启动 cloudformation 模板的 shell 脚本,如果未预设密钥,脚本将创建它并将其上传到 s3 存储桶。
#!/bin/bash
Region=eu-central-1
key=myapp-engine-$Region
Available_key=`aws ec2 describe-key-pairs --key-name $key | grep KeyName | awk -F\" 'print $4'`
if [ "$key" = "$Available_key" ]; then
echo "Key is available."
else
echo "Key is not available: Creating new key"
aws ec2 create-key-pair --key-name $key --region $Region > myapp-engine-$Region.pem
aws s3 cp myapp-engine-$Region.pem s3://mybucket/myapp-engine-$Region.pem
fi
##### create stack #########
/usr/local/bin/aws cloudformation deploy --stack-name myapp-engine --template-file ./lc.yml --parameter-overrides file://./config.json --region $Region
以下是 CloudFormation 启动配置堆栈示例,您可以在其中传递密钥。
Resources:
renderEnginelc:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId:
Ref: "AMIID"
SecurityGroups:
- Fn::ImportValue:
!Sub "$SGStackName-myapp"
InstanceType:
Ref: InstanceType
LaunchConfigurationName : !Join [ "-", [ !Ref Environment, !Ref ApplicationName, lc ] ]
KeyName: !Join [ "-", [ !Ref KeyName, !Ref AWS::Region ] ]
传递 KeyName 的参数值为“myapp-engine”,它将根据 AWS::Region 考虑一个区域
【讨论】:
以上是关于我们能否通过 AWS Cloudformation 动态创建密钥对并将 .PEM 文件复制到 EC2 Linux 实例的主要内容,如果未能解决你的问题,请参考以下文章
Cloudformation 设计器能否为未使用 CFT 启动的资源生成可视化
AWS::CloudFormation::Init 它是如何工作的?
通过 CloudFormation 为现有表添加自动缩放到 AWS DynamoDB