Package: cfn-encrypt
# 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 oftype SecureString in cloudformation. It does this by a custom resourcecalled SecureParameter#### Encrypt ####The custom resource expects base64 encoded input and outputs base64encrypted blobIt supports encryption context#### SecureParameter ####Takes name, value, description and KeyIdIf 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 thekey is located in another AWS account make sure that it allows theaccount you create the stack in *Encrypt* action on the key.#### Parameter: PlainText ####This is just a string that will test the encryption and secure parameterfunctionality.### 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 thelog group that might contain valuable information* Supply the KMS key arn that you want to use, and optionally a value thatyou want to encrypt.* outputs: `KmsKeyArn, LambdaArn, EncryptedValue`* exports: all outputs are exported and their names are prepended withthe name of the stack### How do i use it other stacks? ###Use the example template to provision the lambda function. The exampletemplate 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 wascreated 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 setNoEcho 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 wascreated 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 setNoEcho 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 wascreated 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 repository2. Make changes3. Issue a PREvery PR should be backed by an issue requesting a change.