In AWS CloudFormation there is no way to generate a private key pair. As a result, you always have manual work. You need to generate a ssh key, import it into AWS and finally pass the name to your CloudFormation template. This is clumsy, manual work which prevents us from fully automating the deployment of our infrastructure.
With Custom CloudFormation Resource we put an end to that. RSA keys are generated as a CloudFormation Resource and
the private key is stored in the EC2 parameter store, while the public key can be imported as a EC2 key pair. This means that we fully
automated the deployment of our infrastructure, while at the same time we get to control access to the private key.
How does it work?
It is quite easy: you combine the CloudFormation resource Custom::RSAKey with the Custom::KeyPair, as follows:
Resources:
PrivateKey:
Type: Custom::RSAKey
Properties:
Name: /demo/private-key
ServiceToken: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:binxio-cfn-secret-provider'
KeyPair:
Type: Custom::KeyPair
DependsOn: PrivateKey
Properties:
Name: CustomKeyPair
PublicKeyMaterial: !GetAtt 'PrivateKey.PublicKey'
ServiceToken: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:binxio-cfn-secret-provider'
After the deployment, both the private key and the ec2 key pair are created. The private key can be found in the Parameter Store under the name /demo/private-key
and the ec2 key pair under the name CustomKeyPair
.
The Custom::RSAKey returns the RSA public key in the attribute PublicKey
and in PublicKeyPEM
in OpenSSL and PEM format respectively.
Installation
To install these Custom Resources, type:
git clone https://github.com/binxio/cfn-secret-provider.git
cd cfn-secret-provider
aws cloudformation create-stack
--capabilities CAPABILITY_IAM
--stack-name cfn-secret-provider
--template-body
file://cloudformation/cfn-custom-resource-provider.yaml
aws cloudformation wait stack-create-complete
--stack-name cfn-secret-provider
This CloudFormation template will use our pre-packaged provider from:
s3://binxio-public-{{AWS::Region}}/lambdas/cfn-secret-provider-latest.zip
Demo
To install the simple sample from this blog post, type:
aws cloudformation create-stack
--capabilities CAPABILITY_NAMED_IAM
--stack-name cfn-secret-provider-demo
--template-body file://cloudformation/demo-stack.yaml
aws cloudformation wait stack-create-complete
--stack-name cfn-secret-provider-demo
to validate the result, type:
aws ssm get-parameter --parameter-name /demo/my-private-key --with-decryption
aws ec2 describe-key-pairs --key-name cfn-secret-provider-demo-custom-key-pair
Conclusion
By using the Custom CloudFormation Secret provider you can completely automate your infrastructure, including the generation of private keys required to start your ec2 instances. At the same time, the private key is safely encrypted in the parameter store, where access can be audited and controlled.