Blog

Deploying private key pairs with AWS CloudFormation

25 Oct, 2017
Xebia Background Header Wave

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. Fork me on GitHub
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.

Mark van Holsteijn
Mark van Holsteijn is a senior software systems architect at Xebia Cloud-native solutions. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts