10
votes

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,
      ]
    }
2
Documentation currently states lifecycle blocks cannot be made dynamic.Matt Schuchard

2 Answers

9
votes

No, you can't.

From the lifecycle: Lifecycle Customizations documentation:

The lifecycle settings all effect 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.

4
votes

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,
    ),
  ])
}