Cleaning a template that contains a lamba function makes the code unreadable
reidca opened this issue · 3 comments
reidca commented
The lambda function
LambdaDeployFunction:
Type: AWS::Lambda::Function
DependsOn: LambdaDeployFunctionExecutionRole
Properties:
Handler: "index.handler"
Role: !GetAtt LambdaDeployFunctionExecutionRole.Arn
Code:
ZipFile: !Sub |
import boto3
import json
import logging
import cfnresponse
import time
from botocore.exceptions import ClientError
def handler(event, context):
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.info (f"Input parameters from cloud formation: {event}")
responseData = {}
if (event["RequestType"] == 'Delete'):
logger.info("Responding to delete event...")
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
try:
lambdaClient = boto3.client('lambda')
s3Bucket = event['ResourceProperties']['S3Bucket']
s3Key = event['ResourceProperties']['S3Key']
functionName = event['ResourceProperties']['FunctionName']
logger.info("Updating the function code for Lambda function '{}' to use the code stored in S3 bucket '{}' at key location '{}'".format(functionName, s3Bucket, s3Key))
logger.info("Sleeping for 5 seconds to allow IAM permisisons to take effect")
time.sleep(5)
response = lambdaClient.update_function_code(
FunctionName=functionName,
S3Bucket='{}'.format(s3Bucket),
S3Key='{}'.format(s3Key),
Publish=True)
responseValue = "Function: {}, Version: {}, Last Modified: {}".format(response["FunctionName"],response["Version"],response["LastModified"])
responseData['Data'] = responseValue
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, response["FunctionArn"])
except ClientError as e:
errorMessage = e.response['Error']['Message']
logger.error(errorMessage)
cfnresponse.send(event, context, cfnresponse.FAILED, responseData)
Runtime: "python3.6"
Timeout: "30"
Was converted to:
LambdaDeployFunction:
Type: AWS::Lambda::Function
DependsOn: LambdaDeployFunctionExecutionRole
Properties:
Handler: index.handler
Role: !GetAtt 'LambdaDeployFunctionExecutionRole.Arn'
Code:
ZipFile: !Sub "import boto3\nimport json\nimport logging\nimport cfnresponse\n\
import time\nfrom botocore.exceptions import ClientError\n\ndef handler(event,\
\ context):\n logger = logging.getLogger()\n logger.setLevel(logging.INFO)\n\
\ logger.info (f\"Input parameters from cloud formation: {event}\")\n \
\ responseData = {}\n if (event[\"RequestType\"] == 'Delete'):\n logger.info(\"\
Responding to delete event...\")\n cfnresponse.send(event, context, cfnresponse.SUCCESS,\
\ responseData)\n \n try: \n lambdaClient = boto3.client('lambda')\n\
\ s3Bucket = event['ResourceProperties']['S3Bucket']\n s3Key = event['ResourceProperties']['S3Key']\n\
\ functionName = event['ResourceProperties']['FunctionName']\n logger.info(\"\
Updating the function code for Lambda function '{}' to use the code stored\
\ in S3 bucket '{}' at key location '{}'\".format(functionName, s3Bucket,\
\ s3Key))\n logger.info(\"Sleeping for 5 seconds to allow IAM permisisons\
\ to take effect\")\n time.sleep(5) \n response = lambdaClient.update_function_code(\n\
\ FunctionName=functionName,\n S3Bucket='{}'.format(s3Bucket),\n\
\ S3Key='{}'.format(s3Key),\n Publish=True)\n responseValue\
\ = \"Function: {}, Version: {}, Last Modified: {}\".format(response[\"\
FunctionName\"],response[\"Version\"],response[\"LastModified\"])\n responseData['Data']\
\ = responseValue\n cfnresponse.send(event, context, cfnresponse.SUCCESS,\
\ responseData, response[\"FunctionArn\"])\n except ClientError as e:\n\
\ errorMessage = e.response['Error']['Message']\n logger.error(errorMessage)\n\
\ cfnresponse.send(event, context, cfnresponse.FAILED, responseData)\n"
Runtime: python3.6
Timeout: '30'
I think it should leave the code as it is because it is unreadable now and impossible to maintain.
stilvoid commented
Yep, you're completely right there! I'll look into this shortly.
ryansb commented
I've got a (partial) solution for this. It doesn't work combining longform pipe-strings with !Sub
and friends, but for this template:
{
"LambdaDeployFunction": {
"Type": "AWS::Lambda::Function",
"DependsOn": "LambdaDeployFunctionExecutionRole",
"Properties": {
"Handler": "index.handler",
"Role": {
"Fn::GetAtt": [
"LambdaDeployFunctionExecutionRole",
"Arn"
]
},
"Code": {
"ZipFile": "import boto3\nimport json\nimport logging\nimport cfnresponse\nimport time\nfrom botocore.exceptions import ClientError\n\ndef handler(event, context):\n logger = logg
},
"Runtime": "python3.6",
"Timeout": "30"
}
}
}
It will correctly use a pipe-string for the ZipFile
.
LambdaDeployFunction:
Type: AWS::Lambda::Function
DependsOn: LambdaDeployFunctionExecutionRole
Properties:
Handler: index.handler
Role: !GetAtt 'LambdaDeployFunctionExecutionRole.Arn'
Code:
ZipFile: |
import boto3
import json
import logging
import cfnresponse
import time
from botocore.exceptions import ClientError
def handler(event, context):
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.info (f"Input parameters from cloud formation: {event}")
responseData = {}
if (event["RequestType"] == 'Delete'):
logger.info("Responding to delete event...")
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
try:
lambdaClient = boto3.client('lambda')
s3Bucket = event['ResourceProperties']['S3Bucket']
s3Key = event['ResourceProperties']['S3Key']
functionName = event['ResourceProperties']['FunctionName']
logger.info("Updating the function code for Lambda function '{}' to use the code stored in S3 bucket '{}' at key location '{}'".format(functionName, s3Bucket, s3Key))
logger.info("Sleeping for 5 seconds to allow IAM permisisons to take effect")
time.sleep(5)
response = lambdaClient.update_function_code(
FunctionName=functionName,
S3Bucket='{}'.format(s3Bucket),
S3Key='{}'.format(s3Key),
Publish=True)
responseValue = "Function: {}, Version: {}, Last Modified: {}".format(response["FunctionName"],response["Version"],response["LastModified"])
responseData['Data'] = responseValue
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, response["FunctionArn"])
except ClientError as e:
errorMessage = e.response['Error']['Message']
logger.error(errorMessage)
cfnresponse.send(event, context, cfnresponse.FAILED, responseData)
Runtime: python3.6
Timeout: '30'
See #52 for the code fix