@flomotlik I have a solution for this now. Basically I have a custom CloudFormation resource which grabs the zip file and injects a file containing the template references I need and then replaces the original zip in S3. The lambda function DependsOn this pre-processing step.
The code for my solution is below. In this case, I’m deploying “LambdaFunction” and I want to inject a reference to “ABucket” into that function. I’ve created a custom resource "LambdaSettings to specify the settings I want to inject. The other lambda, “SettingsFunction” simply grabs the zip from S3, injects the settings and replaces the original zip. The only prior knowledge required is the zip file location. Obviously I’ve omitted the permission and role resources etc. I inject a json file below, but a settings.py would be better.
"SettingsFunction": {
"Type" : "AWS::Lambda::Function",
"Properties" : {
"Code": {
"ZipFile": {"Fn::Join": ["\n", [
"import boto3",
"import cfnresponse",
"import io",
"import json",
"import zipfile",
"def handler(event, context):",
" bucket = event['ResourceProperties']['Bucket']",
" key = event['ResourceProperties']['Key']",
" client = boto3.client('s3')",
" if event['RequestType'] == 'Delete':",
" return cfnresponse.send(event, context, 'SUCCESS', {})",
" buff = io.BytesIO()",
" client.download_fileobj(bucket, key, buff)",
" with zipfile.ZipFile(buff, 'a') as zip_file:",
" info = zipfile.ZipInfo('settings.json')",
" info.external_attr = 0777 << 16L",
" zip_file.writestr(info, json.dumps(event['ResourceProperties']['Settings']))",
" zip_file.close()",
" buff.seek(0)",
" client.upload_fileobj(buff, bucket, key)",
" return cfnresponse.send(event, context, 'SUCCESS', {})"
]]}
},
"Handler": "index.handler",
"Runtime": "python2.7",
"Timeout": "300"
},
},
"ABucket": {
"Type": "AWS::S3::Bucket",
},
"LambdaSettings" : {
"Type": "Custom::Settings",
"Properties": {
"ServiceToken" : {"Fn::Join": [":", [
"arn:aws:lambda",
{"Ref": "AWS::Region"},
{"Ref": "AWS::AccountId"},
"function",
{"Ref": "SettingsFunction"}
]]},
"Bucket": deploy_bucket,
"Key": deploy_key,
"Settings": {
"ABucket": {"Ref": "ABucket"}
}
}
},
"LambdaFunction": {
"Type" : "AWS::Lambda::Function",
"DependsOn": {"Ref": "LambdaSettings"},
"Propertes": {
"Code": {
'S3Bucket': deploy_bucket,
'S3Key': deploy_key
}
}
}
I would like to extend serverless to do exactly this so I can ditch my custom deployment tools and switch to serverless. Its not clear to me if I need to extend serverless itself or if I can implement this feature via a plugin.