Sign in
Menu
Sign up
Docs
Operational rulesRule catalog

Ignore deployed artifacts

For platform engineers deciding whether to apply lifecycle_ignore_deployed_artifacts: what it changes, how to enable it, and how to check it worked.

Adds ignore_changes for the artifact pointer a deployment pipeline rewrites on Lambda functions and ECS services. The next plan stops rolling the deployed version back.

What this rule does

Adds a lifecycle { ignore_changes = [...] } block to each matching resource. Terraform and OpenTofu will ignore external changes to the listed attributes on subsequent plans.

Ignored attributes: s3_key, s3_object_version, source_code_hash, image_uri Adds a lifecycle { ignore_changes = [...] } block to each matching resource. Terraform and OpenTofu will ignore external changes to the listed attributes on subsequent plans.

Ignored attributes: task_definition

Affected resources

ResourceServiceWhy
aws_lambda_functionAWS LambdaThe zip in S3, its object version, its hash, or the container image a pipeline deploys
aws_ecs_serviceAmazon ECSThe task definition revision a deployer publishes

Before and after

Before (a module without the change):

resource "aws_lambda_function" "this" {
  # ... resource configuration ...

  tags = var.tags
}

After (with Ignore deployed artifacts applied):

resource "aws_lambda_function" "this" {
  # ... resource configuration ...

  tags = var.tags

  lifecycle {
    ignore_changes = [s3_key, s3_object_version, source_code_hash, image_uri]
  }
}

Before (a module without the change):

resource "aws_lambda_function" "this" {
  # ... resource configuration ...

  tags = var.tags
}

After (with Ignore deployed artifacts applied):

resource "aws_lambda_function" "this" {
  # ... resource configuration ...

  tags = var.tags

  lifecycle {
    ignore_changes = [task_definition]
  }
}

The only change is the rule transformation. All existing arguments, outputs, and module behavior remain identical.

The example above is illustrative. To see this rule run for real, open it in the Rules Playground: it applies lifecycle_ignore_deployed_artifacts to a reviewed upstream module that declares the resources this rule targets, and shows the diff the registry would serve. No account needed.

Why this rule exists

When a pipeline deploys code by uploading a new zip or image, or by publishing a new task definition revision, Terraform's state still holds the previous pointer. The next plan reads the live value as drift and proposes putting the old version back.

The fix is ignore_changes on exactly those attributes, and a lifecycle block cannot be passed into an upstream module as a variable.

RepositoryIssueTitle
hashicorp/terraform#27360A method to override configuration and meta arguments within a module
hashicorp/terraform#24188Support for dynamic blocks and meta-arguments
hashicorp/terraform-provider-aws#19583Provider produced inconsistent final plan / an invalid new value for .tags_all

Limitations this rule answers

Per-module pages under Workarounds where this rule is the answer, each with the native workaround first and the diff the rule makes:

Default configuration

These are the values the rule ships with. Parameters never travel in a module source URL, so a rule named there runs with exactly these defaults. Your organization sets them per rule, in its Baseline or in a ruleset.

ParameterTypeDefaultDescription
lambda_ignore_changeslist(string)["s3_key", "s3_object_version", "source_code_hash", "image_uri"]Attributes naming the deployed Lambda artifact (zip in S3, its version, its hash, or the container image). Override to [] to contribute nothing to the merged set
lambda_resource_typeslist(string)["aws_lambda_function"]Resource types carrying the Lambda artifact pointer
ecs_service_ignore_changeslist(string)["task_definition"]Attributes naming the deployed ECS task definition revision. Assumes an external deployer publishes revisions; if Terraform publishes them this pins the service to a stale revision. Override to [] to contribute nothing to the merged set
ecs_service_resource_typeslist(string)["aws_ecs_service"]Resource types carrying the ECS task definition pointer

The HCL this rule is written in, with its parameters and the transformers it runs, is published at lifecycle_ignore_deployed_artifacts.

How to enable

On a framework host, add the rule on top of your organization's Baseline with ?add_rules= in the HTTPS module source:

module "lambda" {
  source = "https://soc2.compliance.tf/terraform-aws-modules/lambda/aws?version=x.y.z&add_rules=lifecycle_ignore_deployed_artifacts"
}

On your organization's host, an org admin adds the rule to the Baseline, which reaches every module served from that host, or to a named ruleset that a module selects with ?ruleset=:

module "lambda" {
  source = "https://bobthecorp.compliance.tf/terraform-aws-modules/lambda/aws?version=x.y.z&ruleset=<ruleset-name>"
}

Replace x.y.z with the release you use and bobthecorp with your organization's alias. Which parameters each host accepts, and which it refuses with a 400, is on Rulesets in the console.

How to check it worked

Read compliancetf-manifest.json in the module you received. Its entry for this rule carries an outcome: enforced means the change was made, not_applicable means nothing matched - no resource of a targeted type, or the module already carried the identical change. Do not infer enforcement from a successful terraform init; a rule that changes nothing also inits cleanly.

Known limits

  • terraform-aws-ecs has its own ignore_task_definition_changes, which moves the service to a new state address; this rule ignores task_definition on the resource where it is. terraform-aws-lambda has ignore_source_code_hash, which covers a local zip's hash only, not s3_key, s3_object_version or image_uri.
  • Lambda: only s3_key, s3_object_version, source_code_hash and image_uri by default; ECS: only task_definition. Each list is a parameter and an organization can set it to [] to contribute nothing for that resource type.
  • Only aws_lambda_function and aws_ecs_service. Aliases, published Lambda versions and ECS task definitions themselves are not touched.
  • Does not deploy anything. It only stops Terraform from reverting what the deployer wrote.
  • Only .tf and .tofu files are read. Modules written in JSON syntax (.tf.json, .tofu.json) are left untouched.
  • Only the module's own directory and its first-level modules/* submodules are processed. Modules that this module calls by source URL are separate downloads and are handled on their own request.
  • Works with Terraform 1.x and OpenTofu 1.6 and later. The rule reads ordinary HCL, and anything it changes stays ordinary HCL.

Break-glass path

On a framework host, add ?rules=-lifecycle_ignore_deployed_artifacts to the module source URL and run terraform init; the source changed, so Terraform installs a fresh copy without this rule. When you are done, remove the override and run terraform init again to restore it. On your organization's host the parameter is refused with a 400 rather than ignored. The rule comes from the organization's configuration: a Baseline rule applies to every module served from the bare organization form, so an admin disables it for the duration of the operation, or keeps it out of the Baseline and in a ruleset that only the modules needing it select. On a project environment the posture is the bound snapshot and its waivers. See Baseline rules and rulesets.

Failure modes

ScenarioResult
Rule targets a module with no matching resource typesNo-op. Module is delivered unchanged and the manifest records not_applicable.
Terraform is also the deployerA new artifact set through Terraform is ignored on the next plan and never applied. Do not enable the rule for that module.
The resource already carries an ignore_changes listThe list is kept and the attributes are merged in; nothing already ignored is removed.

On this page

Ask AI about this

Help improve this page