Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform conditionally apply lifecycle block

Tags:

terraform

Can you conditionally apply lifecycle blocks to resources in Terraform 0.12.

For example if I wanted to add this block to an AWS ASG resource based of a parameter passed to the module.

    lifecycle {
      ignore_changes = [
       target_group_arns,
      ]
    }
like image 442
Alastair Montgomery Avatar asked Jun 17 '20 11:06

Alastair Montgomery


People also ask

What is one disadvantage of using dynamic blocks in Terraform?

Overuse of dynamic blocks can make configuration hard to read and maintain, so we recommend using them only when you need to hide details in order to build a clean user interface for a re-usable module. Always write nested blocks out literally where possible.

How do I ignore changes in Terraform module?

When you want Terraform to ignore changes between subsequent apply commands you can use the lifecycle ignore_changes meta-argument. The ignore_changes argument means that Terraform will set the value when the resource is first deployed and then forever ignore any changes to it.

What is lifecycle block in Terraform?

lifecycle is a nested block that can appear within a resource block. The lifecycle block and its contents are meta-arguments, available for all resource blocks regardless of type.


Video Answer


2 Answers

No, you can't.

From the The lifecycle Meta-Argument documentation:

The lifecycle settings all affect how Terraform constructs and traverses the dependency graph. As a result, only literal values can be used because the processing happens too early for arbitrary expression evaluation.

While that doesn't explicitly forbid for_each or other dynamic use which would achieve your goal, such constructs are not determinable until later in execution.

The best current workaround is two separate copies of the resource, one with this block and one without:

lifecycle {
  ignore_changes = [
   target_group_arns,
  ]
}

Hopefully, a future version of Terraform will support dynamic lifecycle blocks and non-constant expressions within them.

like image 72
Alain O'Dea Avatar answered Oct 23 '22 14:10

Alain O'Dea


Thanks for the comments answering the question. Best solution for the moment seems to duplicate the resource so that there is one with life_cycle block and one without and control them with count test.

resource "aws_autoscaling_group" "asg" {
  count = var.enabled && var.manage_targets ? 1 : 0

  name                = var.name
  vpc_zone_identifier = var.subnets

  launch_configuration = join("", aws_launch_configuration.lc.*.id)
  load_balancers       = var.load_balancers
  target_group_arns    = var.target_group_arns

  min_size             = var.min
  max_size             = var.max
  default_cooldown     = var.cooldown
  termination_policies = var.termination_policies

  health_check_grace_period = var.health_check_grace_period
  health_check_type         = var.health_check_type

  enabled_metrics = var.enabled_metrics

  tags = flatten([
    {
      key                 = "Name"
      value               = var.name
      propagate_at_launch = true
    },
    {
      key                 = "Environment"
      value               = var.envname
      propagate_at_launch = true
    },
    {
      key                 = "Service"
      value               = var.service
      propagate_at_launch = true
    },
    var.extra_tags,
    slice(
      [{
        "key"                 = "Patch Group"
        "value"               = var.patch_group
        "propagate_at_launch" = true
      }],
      var.patch_group == "" ? 1 : 0,
      1,
    ),
  ])
}

resource "aws_autoscaling_group" "asg_unmanaged_targets" {
  count = var.enabled && !var.manage_targets ? 1 : 0

  name                = var.name
  vpc_zone_identifier = var.subnets

  launch_configuration = join("", aws_launch_configuration.lc.*.id)
  load_balancers       = var.load_balancers
  target_group_arns    = var.target_group_arns

  min_size             = var.min
  max_size             = var.max
  default_cooldown     = var.cooldown
  termination_policies = var.termination_policies

  health_check_grace_period = var.health_check_grace_period
  health_check_type         = var.health_check_type

  enabled_metrics = var.enabled_metrics

  lifecycle {
    ignore_changes = [
     target_group_arns,
    ]
  }

  tags = flatten([
    {
      key                 = "Name"
      value               = var.name
      propagate_at_launch = true
    },
    {
      key                 = "Environment"
      value               = var.envname
      propagate_at_launch = true
    },
    {
      key                 = "Service"
      value               = var.service
      propagate_at_launch = true
    },
    var.extra_tags,
    slice(
      [{
        "key"                 = "Patch Group"
        "value"               = var.patch_group
        "propagate_at_launch" = true
      }],
      var.patch_group == "" ? 1 : 0,
      1,
    ),
  ])
}
like image 26
Alastair Montgomery Avatar answered Oct 23 '22 14:10

Alastair Montgomery