Terraformmodule,whichcreatesalmostallsupportedAWSLambdaresourcesaswellastakingcareofbuildingandpackagingofrequiredLambdadependenciesforfunctionsandlayers.
ThisTerraformmoduleisthepartofserverless.tfframework,whichaimstosimplifyalloperationswhenworkingwiththeserverlessinTerraform:
Buildandinstalldependencies-readmore.RequiresPython3.6ornewer.Create,store,andusedeploymentpackages-readmore.Create,update,andpublishAWSLambdaFunctionandLambdaLayer-seeusage.CreatestaticanddynamicaliasesforAWSLambdaFunction-seeusage,seemodules/alias.Docomplexdeployments(eg,rolling,canary,rollbacks,triggers)-readmore,seemodules/deploy.FeaturesBuilddependenciesforyourLambdaFunctionandLayer.SupportbuildslocallyandinDocker(withorwithoutSSHagentsupportforprivatebuilds).Createdeploymentpackageordeployexisting(previouslybuiltpackage)fromlocal,fromS3,fromURL,orfromAWSECRrepository.StoredeploymentpackageslocallyorintheS3bucket.SupportalmostallfeaturesofLambdaresources(function,layer,alias,etc.)Lambda@EdgeConditionalcreationformanytypesofresources.Controlexecutionofnearlyanystepintheprocess-build,package,storepackage,deploy,update.ControlnearlyallaspectsofLambdaresources(provisionedconcurrency,VPC,EFS,dead-letternotification,tracing,asyncevents,eventsourcemapping,IAMrole,IAMpolicies,andmore).Supportintegrationwithotherserverless.tfmoduleslikeHTTPAPIGateway(seeexamplesthere).UsageLambdaFunction(storepackagelocally)module"lambda_function"{source="terraform-aws-modules/lambda/aws"function_name="my-lambda1"description="Myawesomelambdafunction"handler="index.lambda_handler"runtime="python3.8"source_path="../src/lambda-function1"tags={Name="my-lambda1"}}LambdaFunctionandLambdaLayer(storepackagesonS3)module"lambda_function"{source="terraform-aws-modules/lambda/aws"function_name="lambda-with-layer"description="Myawesomelambdafunction"handler="index.lambda_handler"runtime="python3.8"publish=truesource_path="../src/lambda-function1"store_on_s3=trues3_bucket="my-bucket-id-with-lambda-builds"layers=[module.lambda_layer_s3.lambda_layer_arn,]environment_variables={Serverless="Terraform"}tags={Module="lambda-with-layer"}}module"lambda_layer_s3"{source="terraform-aws-modules/lambda/aws"create_layer=truelayer_name="lambda-layer-s3"description="Myamazinglambdalayer(deployedfromS3)"compatible_runtimes=["python3.8"]source_path="../src/lambda-layer"store_on_s3=trues3_bucket="my-bucket-id-with-lambda-builds"}LambdaFunctionswithexistingpackage(prebuilt)storedlocallymodule"lambda_function_existing_package_local"{source="terraform-aws-modules/lambda/aws"function_name="my-lambda-existing-package-local"description="Myawesomelambdafunction"handler="index.lambda_handler"runtime="python3.8"create_package=falselocal_existing_package="../existing_package.zip"}LambdaFunctionorLambdaLayerwiththedeployableartifactmaintainedseparatelyfromtheinfrastructureIfyouwanttomanagefunctioncodeandinfrastructureresources(suchasIAMpermissions,policies,events,etc)inseparateflows(e.g.,differentrepositories,teams,CI/CDpipelines).
Disablesourcecodetrackingtoturnoffdeployments(androllbacks)usingthemodulebysettingignore_source_code_hash=trueanddeployadummyfunction.
Whentheinfrastructureandthedummyfunctionisdeployed,youcanuseexternaltooltoupdatethesourcecodeofthefunction(eg,usingAWSCLI)andkeepusingthismoduleviaTerraformtomanagetheinfrastructure.
Beawarethatchangesinlocal_existing_packagevaluemaytriggerdeploymentviaTerraform.
module"lambda_function_externally_managed_package"{source="terraform-aws-modules/lambda/aws"function_name="my-lambda-externally-managed-package"description="Mylambdafunctioncodeisdeployedseparately"handler="index.lambda_handler"runtime="python3.8"create_package=falselocal_existing_package="./lambda_functions/code.zip"ignore_source_code_hash=true}LambdaFunctionwithexistingpackage(prebuilt)storedinS3bucketNotethatthismoduledoesnotcopyprebuiltpackagesintoS3bucket.ThismodulecanonlystorepackagesitbuildslocallyandinS3bucket.
locals{my_function_source="../path/to/package.zip"}resource"aws_s3_bucket""builds"{bucket="my-builds"acl="private"}resource"aws_s3_bucket_object""my_function"{bucket=aws_s3_bucket.builds.idkey="${filemd5(local.my_function_source)}.zip"source=local.my_function_source}module"lambda_function_existing_package_s3"{source="terraform-aws-modules/lambda/aws"function_name="my-lambda-existing-package-local"description="Myawesomelambdafunction"handler="index.lambda_handler"runtime="python3.8"create_package=falses3_existing_package={bucket=aws_s3_bucket.builds.idkey=aws_s3_bucket_object.my_function.id}}LambdaFunctionsfromContainerImagestoredonAWSECRmodule"lambda_function_container_image"{source="terraform-aws-modules/lambda/aws"function_name="my-lambda-existing-package-local"description="Myawesomelambdafunction"create_package=falseimage_uri="132367819851.dkr.ecr.eu-west-1.amazonaws.com/complete-cow:1.0"package_type="Image"}LambdaLayers(storepackageslocallyandonS3)module"lambda_layer_local"{source="terraform-aws-modules/lambda/aws"create_layer=truelayer_name="my-layer-local"description="Myamazinglambdalayer(deployedfromlocal)"compatible_runtimes=["python3.8"]source_path="../fixtures/python3.8-app1"}module"lambda_layer_s3"{source="terraform-aws-modules/lambda/aws"create_layer=truelayer_name="my-layer-s3"description="Myamazinglambdalayer(deployedfromS3)"compatible_runtimes=["python3.8"]source_path="../fixtures/python3.8-app1"store_on_s3=trues3_bucket="my-bucket-id-with-lambda-builds"}Lambda@EdgeMakesure,youdeployLambda@EdgefunctionsintoUSEast(N.Virginia)region(us-east-1).SeeRequirementsandRestrictionsonLambdaFunctions.
module"lambda_at_edge"{source="terraform-aws-modules/lambda/aws"lambda_at_edge=truefunction_name="my-lambda-at-edge"description="Myawesomelambda@edgefunction"handler="index.lambda_handler"runtime="python3.8"source_path="../fixtures/python3.8-app1"tags={Module="lambda-at-edge"}}LambdaFunctioninVPCmodule"lambda_function_in_vpc"{source="terraform-aws-modules/lambda/aws"function_name="my-lambda-in-vpc"description="Myawesomelambdafunction"handler="index.lambda_handler"runtime="python3.8"source_path="../fixtures/python3.8-app1"vpc_subnet_ids=module.vpc.intra_subnetsvpc_security_group_ids=[module.vpc.default_security_group_id]attach_network_policy=true}module"vpc"{source="terraform-aws-modules/vpc/aws"name="my-vpc"cidr="10.10.0.0/16"#Specifyatleastoneof:intra_subnets,private_subnets,orpublic_subnetsazs=["eu-west-1a","eu-west-1b","eu-west-1c"]intra_subnets=["10.10.101.0/24","10.10.102.0/24","10.10.103.0/24"]}AdditionalIAMpoliciesforLambdaFunctionsThereare6supportedwaystoattachIAMpoliciestoIAMroleusedbyLambdaFunction:
policy_json-JSONstringorheredoc,whenattach_policy_json=true.policy_jsons-ListofJSONstringsorheredoc,whenattach_policy_jsons=trueandnumber_of_policy_jsons>0.policy-ARNofexistingIAMpolicy,whenattach_policy=true.policies-ListofARNsofexistingIAMpolicies,whenattach_policies=trueandnumber_of_policies>0.policy_statements-MapofmapstodefineIAMstatementswhichwillbegeneratedasIAMpolicy.Requiresattach_policy_statements=true.Seeexamples/completeformoreinformation.assume_role_policy_statements-MapofmapstodefineIAMstatementswhichwillbegeneratedasIAMpolicyforassumingLambdaFunctionrole(trustrelationship).Seeexamples/completeformoreinformation.LambdaPermissionsforallowedtriggersLambdaPermissionsshouldbespecifiedtoallowcertainresourcestoinvokeLambdaFunction.
module"lambda_function"{source="terraform-aws-modules/lambda/aws"#...omittedforbrevityallowed_triggers={APIGatewayAny={service="apigateway"source_arn="arn:aws:execute-api:eu-west-1:135367859851:aqnku8akd0/*/*/*"},APIGatewayDevPost={service="apigateway"source_arn="arn:aws:execute-api:eu-west-1:135367859851:aqnku8akd0/dev/POST/*"},OneRule={principal="events.amazonaws.com"source_arn="arn:aws:events:eu-west-1:135367859851:rule/RunDaily"}}}ConditionalcreationSometimesyouneedtohaveawaytocreateresourcesconditionallybutTerraformdoesnotallowusageofcountinsidemoduleblock,sothesolutionistospecifycreatearguments.
module"lambda"{source="terraform-aws-modules/lambda/aws"create=false#todisableallresourcescreate_package=false#tocontrolbuildpackageprocesscreate_function=false#tocontrolcreationoftheLambdaFunctionandrelatedresourcescreate_layer=false#tocontrolcreationoftheLambdaLayerandrelatedresourcescreate_role=false#tocontrolcreationoftheIAMroleandpoliciesrequiredforLambdaFunctionattach_cloudwatch_logs_policy=falseattach_dead_letter_policy=falseattach_network_policy=falseattach_tracing_policy=falseattach_async_event_policy=false#...omitted}Howdoesbuildingandpackagingwork?Thisisoneofthemostcomplicatedpartdonebythemoduleandnormallyyoudon'thavetoknowinternals.
package.pyisPythonscriptwhichdoesit.Makesure,Python3.6ornewerisinstalled.Themainfunctionsofthescriptaretogenerateafilenameofzip-archivebasedonthecontentofthefiles,verifyifzip-archivehasbeenalreadycreated,andcreatezip-archiveonlywhenitisnecessary(duringapply,notplan).
Hashofzip-archivecreatedwiththesamecontentofthefilesisalwaysidenticalwhichpreventsunnecessaryforce-updatesoftheLambdaresourcesunlesscontentmodifies.Ifyouneedtohavedifferentfilenamesforthesamecontentyoucanspecifyextrastringargumenthash_extra.
Whencallingthismodulemultipletimesinoneexecutiontocreatepackageswiththesamesource_path,zip-archiveswillbecorruptedduetoconcurrentwritesintothesamefile.Therearetwosolutions-setdifferentvaluesforhash_extratocreatedifferentarchives,orcreatepackageonceoutside(usingthismodule)andthenpasslocal_existing_packageargumenttocreateotherLambdaresources.
DebugBuildingandpackaginghasbeenhistoricallyhardtodebug(especiallywithTerraform),sowemadeanefforttomakeiteasierforusertoseedebuginfo.Thereare3differentdebuglevels:DEBUG-toseeonlywhatishappeningduringplanningphaseandhowazipfilecontentfilteringincaseofappliedpatterns,DEBUG2-toseemoreloggingoutput,DEBUG3-toseeallloggingvalues,DUMP_ENV-toseeallloggingvaluesandenvvariables(becarefulsharingyourenvvariablesastheymaycontainsecrets!).
Usercanspecifydebuglevellikethis:
exportTF_LAMBDA_PACKAGE_LOG_LEVEL=DEBUG2terraformapplyUsercanenablecommentsinheredocstringsinpatternswhichcanbehelpfulinsomesituations.Todothissetthisenvironmentvariable:
exportTF_LAMBDA_PACKAGE_PATTERN_COMMENTS=trueterraformapplyBuildDependenciesYoucanspecifysource_pathinavarietyofwaystoachievedesiredflexibilitywhenbuildingdeploymentpackageslocallyorinDocker.Youcanuseabsoluteorrelativepaths.Ifyouhaveplacedterraformfilesinsubdirectories,notethatrelativepathsarespecifiedfromthedirectorywhereterraformplanisrunandnotthelocationofyourterraformfile.
Notethat,whenbuildinglocally,filesarenotcopyinganywherefromthesourcedirectorieswhenmakingpackages,weusefastPythonregularexpressionstofindmatchingfilesanddirectories,whichmakespackagingveryfastandeasytounderstand.
SimplebuildfromsingledirectoryWhensource_pathissettoastring,thecontentofthatpathwillbeusedtocreatedeploymentpackageas-is:
source_path="src/function1"
StaticbuildfrommultiplesourcedirectoriesWhensource_pathissettoalistofdirectoriesthecontentofeachwillbetakenandonearchivewillbecreated.
CombinevariousoptionsforextremeflexibilityThisisthemostcompletewayofcreatingadeploymentpackagefrommultiplesourceswithmultipledependencies.Thisexampleisshowingsomeoftheavailableoptions(seeexamples/build-packageformore):
source_path=["src/main-source","src/another-source/index.py",{path="src/function1-dep",patterns=["!.*/.*\\.txt",#Skipalltxtfilesrecursively]},{path="src/python3.8-app1",pip_requirements=true,prefix_in_zip="foo/bar1",},{path="src/python3.8-app2",pip_requirements="requirements-large.txt",patterns=["!vendor/colorful-0.5.4.dist-info/RECORD","!vendor/colorful-.+.dist-info/.*","!vendor/colorful/__pycache__/?.*",]},{path="src/python3.8-app3",commands=["npminstall",":zip"],patterns=["!.*/.*\\.txt",#Skipalltxtfilesrecursively"node_modules/.+",#Includeallnode_modules],},{path="src/python3.8-app3",commands=["gobuild"],patterns=<<ENDbin/.*abc/def/.*END}]Fewnotes:
Allargumentsexceptpathareoptional.patterns-ListofPythonregexfilenamesshouldsatisfy.Defaultvalueis"includeeverything"whichisequaltopatterns=[".*"].Thiscanalsobespecifiedasmultilineheredocstring(nocommentsallowed).Someexamplesofvalidpatterns:!.*/.*\.txt#Filteralltxtfilesrecursivelynode_modules/.*#Includeemptydirorwithacontentifitexistsnode_modules/.+#Includefullnonemptynode_modulesdirwithitscontentnode_modules/#Includenode_modulesitselfwithoutitscontent#It'salsoawaytoincludeanemptydirifitexistsnode_modules#Includeafileoranexistingdironly!abc/.*#Filterouteverythinginanabcfolderabc/def/.*#Re-includeeverythinginabc/defsubfolder!abc/def/hgk/.*#Filteroutagaininabc/def/hgksubfoldercommands-Listofcommandstorun.Ifspecified,thisargumentoverridespip_requirements.:zip[source][destination]isaspecialcommandwhichcreatescontentofcurrentworkingdirectory(firstargument)andplacesitinsideofpath(secondargument).pip_requirements-Controlswhethertoexecutepipinstall.Settofalsetodisablethisfeature,truetorunpipinstallwithrequirements.txtfoundinpath.Orsettoanotherfilenamewhichyouwanttouseinstead.prefix_in_zip-Ifspecified,willbeusedasaprefixinsidezip-archive.Bydefault,everythinginstallsintotherootofzip-archive.BuildinginDockerIfyourLambdaFunctionorLayerusessomedependenciesyoucanbuildtheminDockerandhavethemincludedintodeploymentpackage.Hereishowyoucandoit:
build_in_docker=truedocker_file="src/python3.8-app1/docker/Dockerfile"docker_build_root="src/python3.8-app1/docker"docker_image="lambci/lambda:build-python3.8"runtime="python3.8"#SettingruntimeisrequiredwhenbuildingpackageinDockerandLambdaLayerresource.Usingthismoduleyoucaninstalldependenciesfromprivatehosts.Todothis,youneedforforwardSSHagent:
docker_with_ssh_agent=trueDeploymentpackage-CreateoruseexistingBydefault,thismodulecreatesdeploymentpackageandusesittocreateorupdateLambdaFunctionorLambdaLayer.
Sometimes,youmaywanttoseparatebuildofdeploymentpackage(eg,tocompileandinstalldependencies)fromthedeploymentofapackageintotwoseparatesteps.
Whencreatingarchivelocallyoutsideofthismoduleyouneedtosetcreate_package=falseandthenargumentlocal_existing_package="existing_package.zip".Alternatively,youmayprefertokeepyourdeploymentpackagesintoS3bucketandprovideareferencetothemlikethis:
create_package=falses3_existing_package={bucket="my-bucket-with-lambda-builds"key="existing_package.zip"}UsingdeploymentpackagefromremoteURLThiscanbeimplementedintwosteps:downloadfilelocallyusingCURL,andpasspathtodeploymentpackageaslocal_existing_packageargument.
locals{package_url="https://raw.githubusercontent.com/terraform-aws-modules/terraform-aws-lambda/master/examples/fixtures/python3.8-zip/existing_package.zip"downloaded="downloaded_package_${
评论