My Terraform code keeps reporting changes after apply although the plan has been correctly applied.
Terraform and provider version:
Terraform v1.1.7
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v4.6.0
resource "aws_codepipeline" "this" {
name = "${lookup(var.tags, "Environment", "")}-terraform-pipeline"
role_arn = aws_iam_role.this.arn
artifact_store {
location = data.aws_s3_bucket.codepipeline_bucket.bucket
type = "S3"
}
dynamic "stage" {
for_each = local.stages
content {
name = stage.value.name
dynamic "action" {
for_each = stage.value.action
content {
name = action.value.name
category = action.value.category
owner = action.value.owner
provider = action.value.provider
version = action.value.version
run_order = action.value.run_order
input_artifacts = action.value.input_artifacts
output_artifacts = action.value.output_artifacts
configuration = action.value.configuration
}
}
}
}
}
locals {
stages = [{
name = "Source"
action = [{
run_order = "1"
category = "Source"
name = "Source"
owner = "AWS"
provider = "CodeCommit"
version = "1"
input_artifacts = []
output_artifacts = ["SourceArtifacts"]
configuration = {
BranchName = "master"
OutputArtifactFormat = "CODEBUILD_CLONE_REF"
RepositoryName = local.repo_name
ProjectName = null
}
}]
}, {
name = "dev"
action = [{
run_order = "2"
category = "Build"
name = "InitAndPlan"
owner = "AWS"
provider = "CodeBuild"
version = "1"
input_artifacts = ["SourceArtifacts"]
output_artifacts = ["PlanArtifacts"]
configuration = {
BranchName = null
OutputArtifactFormat = null
RepositoryName = null
ProjectName = module.codebuild_tf_init_plan.name
}
}, {
run_order = "3"
category = "Approval"
name = "Approve"
owner = "AWS"
provider = "Manual"
version = "1"
input_artifacts = []
output_artifacts = []
configuration = {
BranchName = null
OutputArtifactFormat = null
RepositoryName = null
ProjectName = null
}
}]
}]
}
When I change the run_order
(to be 2 and 2 for the Approval
and InitAndPlan
) stages, then the issue disapears. It is however, not what I want.
The Approve
stages needs to be executed after the InitAndPlan
stages.
What do I miss?
As requested, here is the TF plan
Terraform will perform the following actions:
# module.codepipeline.aws_codepipeline.this will be updated in-place
~ resource "aws_codepipeline" "this" {
id = "sandbox-terraform-pipeline"
name = "sandbox-terraform-pipeline"
tags = {}
# (3 unchanged attributes hidden)
~ stage {
name = "dev"
~ action {
~ category = "Build" -> "Approval"
~ configuration = {
- "ProjectName" = "sandbox-terraform-init-plan" -> null
}
~ input_artifacts = [
- "SourceArtifacts",
]
~ name = "InitAndPlan" -> "Approve"
~ output_artifacts = [
- "PlanArtifacts",
]
~ provider = "CodeBuild" -> "Manual"
~ run_order = 2 -> 3
# (2 unchanged attributes hidden)
}
~ action {
~ category = "Approval" -> "Build"
~ configuration = {
+ "ProjectName" = "sandbox-terraform-init-plan"
}
~ input_artifacts = [
+ "SourceArtifacts",
]
~ name = "Approve" -> "InitAndPlan"
~ output_artifacts = [
+ "PlanArtifacts",
]
~ provider = "Manual" -> "CodeBuild"
~ run_order = 3 -> 2
# (2 unchanged attributes hidden)
}
}
# (2 unchanged blocks hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
It's possible only when action
is a set
rather list
.
They might look alike but set
like in other languages, doesn't guarantee order like lists
. More details here & a similar discussion here.
Going forward, in case of such doubts, you could do type
validation of variables like discussed here