<p>There's a need to create an AWS security group rule using Terraform, then triggering a null resource.</p>
<p>E.G.</p>
<ul>
<li>health_blue. (aws_security_group_rule)</li>
<li>wait_for_healthcheck. (null_resource)</li>
</ul>
<p>I have already tried adding a dependency between the security group rule and the null resource, but the null resource is not always triggered, or it not triggered before the rule is created or destroyed.</p>
<p>The null resource needs to be triggered when the security group rule is created, amended, or destroyed.</p>
<p>Here is the config:</p>
<pre><code>resource &quot;aws_security_group_rule&quot; &quot;health_blue&quot; {
  count       = data.external.blue_eks_cluster.result.cluster_status == &quot;online&quot; ? 1 : 0
  description = &quot;LB healthchecks to blue cluster&quot;

  cidr_blocks       = values(data.aws_subnet.eks_gateway).*.cidr_block
  from_port         = 80
  protocol          = &quot;tcp&quot;
  security_group_id = data.aws_security_group.blue_cluster_sg[0].id
  to_port           = 80
  type              = &quot;ingress&quot;
}

resource &quot;null_resource&quot; &quot;wait_for_healhtcheck&quot; {

  triggers = {
    value = aws_security_group_rule.health_blue[0].id
  }

  provisioner &quot;local-exec&quot; {
    command = &quot;echo 'Waiting for 25 seconds'; sleep 25&quot;
  }

  depends_on = [aws_security_group_rule.health_blue]
}
</code></pre>
<p>Any tips or pointers would be much appreciated :~)</p>

Theo Sweeny
<p>With the configuration you showed here, <code>null_resource.wait_for_healhtcheck</code> depends on <code>aws_security_group_rule.health_blue</code>.</p>
<p>(You currently have that dependency specified redundantly: the reference to <code>aws_security_group_rule.health_blue</code> in <code>triggers</code> already establishes the dependency, so the <code>depends_on</code> argument is doing nothing here and I would suggest removing it.)</p>
<p>The general meaning of a dependency in Terraform is that any actions taken against the dependent object must happen after any actions taken against its dependency. In your case, Terraform guarantees that after it has created the plan if there are any actions planned for both of these resources then the action planned for <code>aws_security_group_rule.health_blue</code> will always happen first during the apply step.</p>
<p>You are using the <code>triggers</code> argument of <code>null_resource</code>, which adds an additional behavior that's implemented by the <code>hashicorp/null</code> provider rather than by Terraform Core itself: during planning, <code>null_resource</code> will compare the <code>triggers</code> value from the prior state with the <code>triggers</code> value in the current configuration and if they are different then it will propose the action of replacing the (purely conceptual) <code>null_resource</code> object.</p>
<p>Because <code>triggers</code> includes <code>aws_security_group_rule.health_blue[0].id</code>, <code>triggers</code> will take on a new value each time the security group is planned for creation or replacing. Therefore taken altogether your configuration declares the following:</p>
<ul>
<li>There are either zero or one <code>aws_security_group_rule.health_blue</code> objects.</li>
<li>Each time the <code>id</code> attribute of the security group changes, the <code>null_resource.wait_for_healhtcheck</code> must be replaced.</li>
<li>Whenever creating or replacing <code>null_resource.wait_for_healhtcheck</code>, run the given provisioner.</li>
<li>Therefore, if the <code>id</code> attribute of the security group changes there will always be both a plan to create (or replace) <code>aws_security_group_rule.health_blue</code> <em>and</em> a plan to replace <code>null_resource.wait_for_healhtcheck</code>. The dependency rules mean that the creation of the security group will happen before the creation of the <code>null_resource</code>, and therefore before running the provisioner.</li>
</ul>
<p>Your configuration as shown therefore seems to meet your requirements as stated. However, it does have one inconsistency which could potentially cause a problem: you haven't accounted for what ought to happen if there are zero instances of <code>aws_security_group_rule.health_blue</code>. In that case <code>aws_security_group_rule.health_blue[0].id</code> isn't valid because there isn't a zeroth instance of that resource to refer to.</p>
<p>To address that I would suggest a simplification: the <code>null_resource</code> resource isn't really adding anything here that you couldn't already do with the <code>aws_security_group_rule</code> resource directly:</p>
<pre><code>resource &quot;aws_security_group_rule&quot; &quot;health_blue&quot; {
  count       = data.external.blue_eks_cluster.result.cluster_status == &quot;online&quot; ? 1 : 0
  description = &quot;LB healthchecks to blue cluster&quot;

  cidr_blocks       = values(data.aws_subnet.eks_gateway).*.cidr_block
  from_port         = 80
  protocol          = &quot;tcp&quot;
  security_group_id = data.aws_security_group.blue_cluster_sg[0].id
  to_port           = 80
  type              = &quot;ingress&quot;

  provisioner &quot;local-exec&quot; {
    command = &quot;echo 'Waiting for 25 seconds'; sleep 25&quot;
  }
}
</code></pre>
<p>Provisioners for a resource run as part of the creation action for that resource, and changing the configuration of a security group rule should cause it to get recreated, so with the above configuration the <code>sleep 25</code> command will run each time an instance of the security group rule is created, without any need for a separate resource.</p>
<p>This solution <em>does</em> assume that you only need to run <code>sleep 25</code> when creating (or replacing) the security group rule. The <code>null_resource</code> approach would be needed if the goal were to run a provisioner in response to <em>updating</em> some other resource, because in that case the <code>null_resource</code> resource would act as a sort of adapter to allow treating an update of any value in <code>triggers</code> to be treated as if it were a replacement of a resource.</p>
