Skip to main content

Lambda cloudformation custom resource that use KMS encrypt

Project description

# README #



### What is this repository for? ###

* To encrypt values in cloudformation
* To Create secure ssm parameters in cloudformation
* To Retrieve secure ssm paramters in cloudformation



### What does it do? ###

The repo provides two simple lambda functions
* simple_encrypt.py: exposes the kms encrypt api to cloudformation.
It does this by a custom resource called Encrypt.
* ssm_parameter.py: Makes it possible to create ssm parameters of
type SecureString in cloudformation. It does this by a custom resource
called SecureParameter


#### Encrypt ####

The custom resource expects base64 encoded input and outputs base64
encrypted blob

It supports encryption context

#### SecureParameter ####
Takes name, value, description and KeyId

If the parameter name was not created in this stack update will fail

### How do I get set up? ###

* install the module in via pip
~~~~
pip install cfn-encrypt
~~~~


### template.py ###
This is the template that provision the lambda function.

It takes two parameters

#### Parameter: KmsKeyArn ####
This is the arn of the kms key you want to use for encryption. If the
key is located in another AWS account make sure that it allows the
account you create the stack in *Encrypt* action on the key.


#### Parameter: PlainText ####
This is just a string that will test the encryption and secure parameter
functionality.

### If the stack creation fails ###
Check the log group /aws/lambda/*stack name*


### generate the template ###
~~~~
python template.py > /tmp/encrypt.template
~~~~
* create a stack using `/tmp/encrypt.template`
* Make sure you do not rollback on failure, since that will delete the
log group that might contain valuable information
* Supply the KMS key arn that you want to use, and optionally a value that
you want to encrypt.
* outputs: `KmsKeyArn, LambdaArn, EncryptedValue`
* exports: all outputs are exported and their names are prepended with
the name of the stack



### How do i use it other stacks? ###

Use the example template to provision the lambda function. The example
template will export the arn of the lambdas


##### simple encrypt usage #####
Import the custom resource class
~~~~
from cfn_encrypt import Encrypt, EncryptionContext
~~~~


Create a parameter so you can reference to the template the lambda was
created in
~~~~
encrypt_lambda_stack = t.add_parameter(Parameter(
"EncryptLambdaStack",
Type="String",
Description="Stack name of the encryption lambda"
))
~~~~

Import KmsKeyArn and LambdaArn from the lambda stack
~~~~
kms_key_arn = ImportValue(Sub("${EncryptLambdaStack}-KmsKeyArn"))
lambda_arn = ImportValue(Sub("${EncryptLambdaStack}-EncryptLambdaArn"))
~~~~


Add a parameter for the value you want to encrypt, make sure you set
NoEcho to True
~~~~
my_secret = t.add_parameter(Parameter(
"MySecret",
Type="String",
Description="Enter your secret",
NoEcho=True
))
~~~~


Invoke the lambda
~~~~
encrypted_secret = t.add_resource(Encrypt(
"EncryptedSecret",
ServiceToken=lambda_arn,
Base64Data=Base64(Ref(my_secret)),
KmsKeyArn=kms_key_arn
))
~~~~

If you want to use encryption context.
* Note that encryption context should not be sensitive values.
~~~~
my_encrypted_value_with_context = t.add_resource(Encrypt(
"MyEncryptedValueWithContext",
ServiceToken=lambda_arn,
Base64Data=Base64(Ref(plain_text)),
KmsKeyArn=kms_key_arn,
EncryptionContext=EncryptionContext(
Name="Test",
Value="Test"
)
))
~~~~
The the encrypted parameter can be retrieved base64 encoded using GetAtt
~~~~
GetAtt(encrypted_secret, "CiphertextBase64"),
~~~~



#### ssm parameter usage ####

Import the custom resource class
~~~~
from cfn_encrypt import SecureParameter
~~~~


Create a parameter so you can reference to the template the lambda was
created in
~~~~
encrypt_lambda_stack = t.add_parameter(Parameter(
"EncryptLambdaStack",
Type="String",
Description="Stack name of the encryption lambda"
))
~~~~

Import KmsKeyArn and LambdaArn from the lambda stack
~~~~
kms_key_arn = ImportValue(Sub("${EncryptLambdaStack}-KmsKeyArn"))
lambda_arn = ImportValue(Sub("${EncryptLambdaStack}-EncryptLambdaArn"))
~~~~


Add a parameter for the value you want to encrypt, make sure you set
NoEcho to True
~~~~
my_secret = t.add_parameter(Parameter(
"MySecret",
Type="String",
Description="Enter your secret",
NoEcho=True
))
~~~~


Invoke the lambda
~~~~

my_secure_parameter = t.add_resource(SecureParameter(
"MySecureParameter",
ServiceToken=lambda_arn,
Name="MySecureParameter",
Description="Testing secure parameter",
Value=Ref(my_secret),
KeyId=kms_key_arn
))

~~~~




#### get ssm parameter ####


Import the custom resource class
~~~~
from cfn_encrypt import GetSsmValue
~~~~


Create a parameter so you can reference to the template the lambda was
created in
~~~~
encrypt_lambda_stack = t.add_parameter(Parameter(
"EncryptLambdaStack",
Type="String",
Description="Stack name of the encryption lambda"
))
~~~~

Import KmsKeyArn and LambdaArn from the lambda stack
~~~~
kms_key_arn = ImportValue(Sub("${EncryptLambdaStack}-KmsKeyArn"))
lambda_arn = ImportValue(Sub("${EncryptLambdaStack}-EncryptLambdaArn"))
~~~~




Invoke the lambda
~~~~
my_decrypted_value = t.add_resource(GetSsmValue(
"MyDecryptedValue",
ServiceToken=lambda_arn,
Name="/My/Parameter/Name",
KeyId=kms_key_arn,
Version=5 # Optional

))

Use GetAtt to get information about the parameter
'Name': 'string',
'Type': 'String'|'StringList'|'SecureString',
'KeyId': 'string',
'LastModifiedDate': datetime(2015, 1, 1),
'LastModifiedUser': 'string',
'Description': 'string',
'Value': 'string',
'AllowedPattern': 'string',
'Version': 123

~~~~



### How to contribute and report bugs ###

You can contribute by sending a PR to the repo.

1. Fork the repository
2. Make changes
3. Issue a PR

Every PR should be backed by an issue requesting a change.




Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

cfn_encrypt-0.0.14-py2.py3-none-any.whl (8.6 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file cfn_encrypt-0.0.14-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for cfn_encrypt-0.0.14-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 43b5a7fff7f5388d38e0c7c79f1507eddf1676d3e21f520e5837b74e4284ff30
MD5 f8c0a9ca40f4c529f1330b9ab31aff66
BLAKE2b-256 329c3e8432443c40ed48d076072bcbaf77853d6696a56cc35ecf1837532afc3b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page