×

Deploying private key pairs with AWS CloudFormation

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": {
          "Fn::Join": [ ":", [ "arn:aws:lambda", { "Ref": "AWS::Region" }, { "Ref": "AWS::AccountId" }, "function:binxio-cfn-secret-provider" ] ]
        }
      }
    },
    "KeyPair": {
      "Type": "Custom::KeyPair",
      "DependsOn": "PrivateKey",
      "Properties": {
        "Name": "CustomKeyPair",
        "PublicKeyMaterial": {
                "Fn::GetAtt": [ "PrivateKey", "PublicKey" ]
        },
        "ServiceToken": {
          "Fn::Join": [ ":", [ "arn:aws:lambda", { "Ref": "AWS::Region" }, { "Ref": "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 checkout https://github.com/binxio/cfn-secret-provider
cd cfn-secret-provider

aws cloudformation create-stack \
	--capabilities CAPABILITY_IAM \
	--stack-name cfn-secret-provider \
	--template-body \
	file://cloudformation/cfn-custom-resource-provider.json 

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 \
	--stack-name cfn-secret-provider-demo \
	--template-body file://cloudformation/demo-stack.json

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 CustomKeyPair

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.

If you have any questions, do not hesitate to contact me.

Picture of Mark van Holsteijn
Mark van Holsteijn
Cloud Consultant