- 
      
 - 
        
Save jgautheron/063e9f15773a0f23f4c86b8d59533a12 to your computer and use it in GitHub Desktop.  
Revisions
- 
        
JohnPreston revised this gist
Nov 11, 2016 . 1 changed file with 16 additions and 14 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -13,19 +13,19 @@ def get_password_from_dynamodb(env, stack_name, table_name): Function to get the password out of dynamodb :param env: environment name :param stack_name: name of the stack :param table_name: name of the table storing all the DB passwords etc. :return: string """ client = boto3.resource('dynamodb') table = client.Table(table_name) response = table.get_item( Key={ 'env': env, 'stackname': stack_name } ) if 'Item' in response: if 'passwordbase64' in response['Item']: return response['Item']['passwordbase64'] else: return "No such attribute : passwordbase64" @@ -60,11 +60,13 @@ def send_response(request, response, status=None, reason=None): response['Reason'] = reason if 'ResponseURL' in request and request['ResponseURL']: try: url = urlparse.urlparse(request['ResponseURL']) body = json.dumps(response) https = httplib.HTTPSConnection(url.hostname) https.request('PUT', url.path + '?' + url.query, body) except: print("Failed to send the message to CF") return response @@ -93,15 +95,15 @@ def lambda_handler(event, context): for key in ['Env', 'StackName']: if key not in event['ResourceProperties'] or not event['ResourceProperties'][key]: return send_response( event, response, status='FAILED', reason='The properties Env and StackName must not be empty' ) password_b64 = get_password_from_dynamodb(event['ResourceProperties']['Env'], event['ResourceProperties']['StackName'], event['ResourceProperties']['TableName']) password = decrypt_password_from_b64(password_b64) response['Data'] = {'password': password} response['Reason'] = 'The value was successfully encrypted'  - 
        
JohnPreston revised this gist
Nov 4, 2016 . 1 changed file with 0 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -82,19 +82,14 @@ def lambda_handler(event, context): 'Status': 'SUCCESS' } if 'PhysicalResourceId' in event: response['PhysicalResourceId'] = event['PhysicalResourceId'] else: response['PhysicalResourceId'] = str(uuid.uuid4()) if event['RequestType'] == 'Delete': return send_response(event, response) if event['RequestType'] == 'Update': return send_response(event, response) for key in ['Env', 'StackName']: if key not in event['ResourceProperties'] or not event['ResourceProperties'][key]: return send_response(  - 
        
JohnPreston revised this gist
Nov 4, 2016 . 1 changed file with 0 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -46,9 +46,6 @@ def decrypt_password_from_b64(password_b64): def send_response(request, response, status=None, reason=None): """ :param request: CF lambda settings :param response: object containing the response values :param status: to report to CloudFormation  - 
        
JohnPreston revised this gist
Nov 3, 2016 . 1 changed file with 4 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -105,10 +105,12 @@ def lambda_handler(event, context): reason='The properties Env and StackName must not be empty' ) password_b64 = get_password_from_dynamodb(event['ResourceProperties']['Env'], event['ResourceProperties']['StackName'], event['ResourceProperties']['TableName']) password = decrypt_password_from_b64(password_b64) response['Data'] = {'password': password} response['Reason'] = 'The value was successfully encrypted' return send_response(event, response)  - 
        
JohnPreston revised this gist
Nov 3, 2016 . 1 changed file with 24 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,13 +4,18 @@ import urlparse import json import boto3 import string import random def get_password_from_dynamodb(env, stack_name, table_name): """ Function to get the password out of dynamodb :param env: environment name :param stack_name: name of the stack :table_name: name of the table storing all the DB passwords etc. :return: string """ client = boto3.resource('dynamodb') table = client.Table('lelabboPasswords') response = table.get_item( @@ -27,9 +32,11 @@ def get_password_from_dynamodb(env=None, stack_name=None): else: return "No key found" def decrypt_password_from_b64(password_b64): """ Function to encrypt the password with KMS :param password_b64: b64 string of the encrypted password """ password_encrypted = base64.b64decode(password_b64) client = boto3.client('kms') @@ -38,9 +45,15 @@ def decrypt_password_from_b64(password_b64=None): def send_response(request, response, status=None, reason=None): """ Send our response to the pre-signed URL supplied by CloudFormation If no ResponseURL is found in the request, there is no place to send a response. This may be the case if the supplied event was for testing. :param request: CF lambda settings :param response: object containing the response values :param status: to report to CloudFormation :param reason: Message to report to CloudFormation to explain the status :return: Object with all the reponse objects """ if status is not None: @@ -59,7 +72,12 @@ def send_response(request, response, status=None, reason=None): def lambda_handler(event, context): """ Core function called when Lambda is invoked :param event: The Lambda event params :param context: The Lambda context params :return: Return the response to CloudFormation """ response = { 'StackId': event['StackId'], 'RequestId': event['RequestId'],  - 
        
JohnPreston created this gist
Nov 2, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,96 @@ import base64 import uuid import httplib import urlparse import json import boto3 import string import random def get_password_from_dynamodb(env=None, stack_name=None): client = boto3.resource('dynamodb') table = client.Table('lelabboPasswords') response = table.get_item( Key={ 'environment': env, 'stackname': stack_name } ) if 'Item' in response: if 'passwordbase64' in response['Item']: return response['Item']['passwordbase64'] else: return "No such attribute : passwordbase64" else: return "No key found" def decrypt_password_from_b64(password_b64=None): """ Function to encrypt the password with KMS """ password_encrypted = base64.b64decode(password_b64) client = boto3.client('kms') password = client.decrypt(CiphertextBlob=password_encrypted) return password['Plaintext'] def send_response(request, response, status=None, reason=None): """ Send our response to the pre-signed URL supplied by CloudFormation If no ResponseURL is found in the request, there is no place to send a response. This may be the case if the supplied event was for testing. """ if status is not None: response['Status'] = status if reason is not None: response['Reason'] = reason if 'ResponseURL' in request and request['ResponseURL']: url = urlparse.urlparse(request['ResponseURL']) body = json.dumps(response) https = httplib.HTTPSConnection(url.hostname) https.request('PUT', url.path+'?'+url.query, body) return response def lambda_handler(event, context): response = { 'StackId': event['StackId'], 'RequestId': event['RequestId'], 'LogicalResourceId': event['LogicalResourceId'], 'Status': 'SUCCESS' } # PhysicalResourceId is meaningless here, but CloudFormation requires it if 'PhysicalResourceId' in event: response['PhysicalResourceId'] = event['PhysicalResourceId'] else: response['PhysicalResourceId'] = str(uuid.uuid4()) # There is nothing to do for a delete request if event['RequestType'] == 'Delete': return send_response(event, response) if event['RequestType'] == 'Update': return send_response(event, response) # Encrypt the value using AWS KMS and return the response for key in ['Env', 'StackName']: if key not in event['ResourceProperties'] or not event['ResourceProperties'][key]: return send_response( event, response, status='FAILED', reason='The properties Env and StackName must not be empty' ) password_b64 = get_password_from_dynamodb(event['ResourceProperties']['Env'], event['ResourceProperties']['StackName']) password = decrypt_password_from_b64(password_b64) response['Data'] = {'password': password} response['Reason'] = 'The value was successfully encrypted' return send_response(event, response)