stelligent/config-lint

How to check nested terraform blocks

Opened this issue · 1 comments

Hello,

Assuming I have the following resource:

resource "google_service_account" "sa" {
  account_id   = "sa"
  display_name = "sa"

  lifecycle {
    prevent_destroy = true
  }
}

What would the rule look like that could assert that prevent_destroy is present and true? I assumed:

---
version: 1
description: Google-specific Terraform Rules
type: Terraform
files:
  - "*.tf"
rules:
  - id: PREVENT_DESTROY_IN_SERVICE_ACCOUNT
    message: "Service Account definitions must have prevent_destroy set"
    category: resource
    resources:
      - google_service_account
    assertions:
      - key: lifecycle.prevent_destroy
        op: eq
        value: true

would work, but it fails:

  {
    "AssertionMessage": "lifecycle.prevent_destroy(null) should be equal to true",
    "Category": "resource",
    "CreatedAt": "2020-10-16T14:59:05Z",
    "Filename": "test/sa.tf",
    "LineNumber": 1,
    "ResourceID": "sa",
    "ResourceType": "google_service_account",
    "RuleID": "PREVENT_DESTROY_IN_SERVICE_ACCOUNT",
    "RuleMessage": "Service Account definitions must have prevent_destroy set",
    "Status": "FAILURE"
  }

Figured it out. lifecycle is an array (though I don't understand why).

---
version: 1
description: Google-specific Terraform Rules
type: Terraform
files:
  - "*.tf"
rules:
  - id: PREVENT_DESTROY_IN_SERVICE_ACCOUNT
    message: "Service Account definitions must have prevent_destroy set"
    category: resource
    resources:
      - google_service_account
    assertions:
      - exactly-one:
          key: "lifecycle[]"
          expressions:
            - key: prevent_destroy
              op: is-true