In the AWS SAM template you can reference these parameters like this:
Parameters:IdentityRoleARN:Type:AWS::SSM::Parameter::Value<String>Description:Identity lambda Role ARNDefault:/dev/example/identity_role_arn
The only thing is, you'll still need to run this solution twice (chicken egg problem) to set the AWS SAM created parameters in the Terraform dev.tfvars file. I haven't got a better solution for this yet
Hello! Thanks for your detailed post!! Terraform is the IaC tool of choice of my org, but since it doesn't provide additional support for local lambda testing I'm considering to use SAM too. I'm thinking to setup everything using Terraform except the lambdas. In your solution, everytime you update the lambda code in the sam repo, do you re trigger terraform to update the lambdas? Could you just do this directly from sam repo? Why to still use terraform? Thanks!
"do you re trigger terraform to update the lambdas?"
The trigger is on the Codepipeline configuration for the source code, you could have it trigger on git push to a branch that it will automatically start the pipeline.
"Could you just do this directly from sam repo?"
You can, sam features a deploy feature on the cli tool itself that you can use to deploy the stack directly to AWS. It's the same configuration that is in the CodePipeline build spec file.
"Why to still use terraform?"
I don't particularly like CloudFormation to perform resource deployments with, it's clunky it doesn't work well with changing resource states especially if they happen outside of the tooling for whatever reason. The drift "feature" is pointless without an automated way to correct it. Terraform state recording is much superior to fix Resource drift in my opinion.
Generally I only deploy Lambda related resources via AWS SAM, the API and Lambda's. The rest I configure and manage with Terraform.
Really interesting idea. I followed your example.
In my organziation, we already use CodeBuild and CodePipeline for terraform deployments.
We deploy also our ECS fargate services via terraform and additional CodeDeploy steps.
I mixed our terraform CodeBuild stuff and your example and we have a pipeline which does a terraform plan, approval action with the plan, a terraform deploy and then the create changeset and execute changeset.
For the communication between terraform and CloudFormation I did not use SSM parameters. I defined parameters in the CloudFormation template.
According the SAM / CF documentation you can either override such parameters in CodePipeline or you can specify a configuration.json
The trick I did is that my terraform output is directly the output for the configuration json.
So in my terraform apply step in CodeBuild I do
terraform apply -input=false -lock-timeout=30s ./.pipeline/plan.tfplan
and then I do terraform output -json | jq .configuration_cloudformation.value > configuration.json
Ive actually added the SSM Parameter Store to this solution using this module:
rpstreef / terraform-aws-ssm-parameter-store
Terraform module for AWS Systems Manager Parameter Store
Now we can sync our Terraform created parameters to AWS SAM like this:
In the AWS SAM template you can reference these parameters like this:
The only thing is, you'll still need to run this solution twice (chicken egg problem) to set the AWS SAM created parameters in the Terraform
dev.tfvars
file. I haven't got a better solution for this yetHello! Thanks for your detailed post!! Terraform is the IaC tool of choice of my org, but since it doesn't provide additional support for local lambda testing I'm considering to use SAM too. I'm thinking to setup everything using Terraform except the lambdas. In your solution, everytime you update the lambda code in the sam repo, do you re trigger terraform to update the lambdas? Could you just do this directly from sam repo? Why to still use terraform? Thanks!
Thanks for reading! I'll try and answer below.
"do you re trigger terraform to update the lambdas?"
The trigger is on the Codepipeline configuration for the source code, you could have it trigger on git push to a branch that it will automatically start the pipeline.
"Could you just do this directly from sam repo?"
You can, sam features a deploy feature on the cli tool itself that you can use to deploy the stack directly to AWS. It's the same configuration that is in the CodePipeline build spec file.
"Why to still use terraform?"
I don't particularly like CloudFormation to perform resource deployments with, it's clunky it doesn't work well with changing resource states especially if they happen outside of the tooling for whatever reason. The drift "feature" is pointless without an automated way to correct it. Terraform state recording is much superior to fix Resource drift in my opinion.
Generally I only deploy Lambda related resources via AWS SAM, the API and Lambda's. The rest I configure and manage with Terraform.
Really interesting idea. I followed your example.
In my organziation, we already use CodeBuild and CodePipeline for terraform deployments.
We deploy also our ECS fargate services via terraform and additional CodeDeploy steps.
I mixed our terraform CodeBuild stuff and your example and we have a pipeline which does a terraform plan, approval action with the plan, a terraform deploy and then the create changeset and execute changeset.
For the communication between terraform and CloudFormation I did not use SSM parameters. I defined parameters in the CloudFormation template.
According the SAM / CF documentation you can either override such parameters in CodePipeline or you can specify a configuration.json
The trick I did is that my terraform output is directly the output for the configuration json.
So in my terraform apply step in CodeBuild I do
terraform apply -input=false -lock-timeout=30s ./.pipeline/plan.tfplan
and then I do terraform output -json | jq .configuration_cloudformation.value > configuration.json
My terraform output statement looks like:
output "configuration_cloudformation" {
value = {
Parameters = {
SecurityGroupIds = aws_security_group.lambda.id
LambdaRoleARN = aws_iam_role.jds_monitoring.arn
Tags = var.complete_tags
...
StackPolicy = {
}
}
That kind of chaining would solve the issue, thanks for sharing.