Create a sample IaC validation report

This tutorial describes how you can verify that your infrastructure as code (IaC) doesn't violate your organization policies or Security Health Analytics detectors.

Prepare the environment

  1. Install the Google Cloud CLI.

  2. Configure the gcloud CLI to use your federated identity.

    For more information, see Sign in to the gcloud CLI with your federated identity.

  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Verify that billing is enabled for your Google Cloud project.

  6. Enable the Security posture service and Security Command Center management APIs:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable securityposture.googleapis.com  securitycentermanagement.googleapis.com
  7. Copy the project number. You will need the project number to set the target resource while deploying the posture.
    gcloud projects describe PROJECT_ID
  8. Initialize Terraform:
    terraform init

Create and deploy a posture

  1. In Cloud Shell, launch the Cloud Shell Editor. To launch the editor, click Code Editor Button Open Editor on the toolbar of the Cloud Shell window.

  2. Create a YAML file named example-standard.yaml.

  3. Paste the following code into your file:

name: organizations/ORGANIZATION_ID/locations/global/postures/example-standard
state: ACTIVE
policySets:
- policies:
  - constraint:
      orgPolicyConstraintCustom:
        customConstraint:
          actionType: ALLOW
          condition: "resource.initialNodeCount == 3"
          description: Set initial node count to be exactly 3.
          displayName: fixedNodeCount
          methodTypes:
          - CREATE
          name: organizations/ORGANIZATION_ID/customConstraints/custom.fixedNodeCount
          resourceTypes:
          - container.googleapis.com/NodePool
        policyRules:
        - enforce: true
    policyId: fixedNodeCount
  - constraint:
      securityHealthAnalyticsCustomModule:
        config:
          customOutput: {}
          description: Set MTU for a network to be exactly 1000.
          predicate:
            expression: "!(resource.mtu == 1000)"
          recommendation: Only create networks whose MTU is 1000.
          resourceSelector:
            resourceTypes:
            - compute.googleapis.com/Network
          severity: HIGH
        displayName: fixedMTU
        moduleEnablementState: ENABLED
    policyId: fixedMTU
  - constraint:
      securityHealthAnalyticsModule:
        moduleEnablementState: ENABLED
        moduleName: BUCKET_POLICY_ONLY_DISABLED
    policyId: bucket_policy_only_disabled
  - constraint:
      securityHealthAnalyticsModule:
        moduleEnablementState: ENABLED
        moduleName: BUCKET_LOGGING_DISABLED
    policyId: bucket_logging_disabled
  policySetId: policySet1

Replace ORGANIZATION_ID with your organization ID.

  1. In Cloud Shell, create the posture:

    gcloud scc postures create organizations/ORGANIZATION_ID/locations/global/postures/example-standard --posture-from-file=example-standard.yaml
    
  2. Copy the posture revision ID that the command generates.

  3. Deploy the posture to your project:

    gcloud scc posture-deployments create organizations/ORGANIZATION_ID/locations/global/postureDeployments/example-standard \
    --posture-name=organizations/ORGANIZATION_ID/locations/global/postures/example-standard \
    --posture-revision-id="POSTURE_REVISION_ID" \
    --target-resource=projects/PROJECT_NUMBER
    

    Replace the following:

    • ORGANIZATION_ID: your organization ID.
    • POSTURE REVISION_ID: your posture revision ID that you copied.
    • PROJECT_NUMBER: your project number.

Create the Terraform file and validate

  1. In Cloud Shell, launch the Cloud Shell Editor.

  2. Create a Terraform file named main.tf.

  3. Paste the following code into your file:

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
        }
      }
    }
    
    provider "google" {
      region  = "us-central1"
      zone    = "us-central1-c"
    }
    
    resource "google_compute_network" "example_network"{
      name                            = "example-network-1"
      delete_default_routes_on_create = false
      auto_create_subnetworks         = false
      routing_mode                    = "REGIONAL"
      mtu                             = 100
      project                         = "PROJECT_ID"
    }
    
    resource "google_container_node_pool" "example_node_pool" {
      name               = "example-node-pool-1"
      cluster            = "example-cluster-1"
      project            = "PROJECT_ID"
      initial_node_count = 2
    
      node_config {
        preemptible  = true
        machine_type = "e2-medium"
      }
    }
    
    resource "google_storage_bucket" "example_bucket" {
      name          = "example-bucket-1"
      location      = "EU"
      force_destroy = true
    
      project = "PROJECT_ID"
    
      uniform_bucket_level_access = false
    }
    

    Replace PROJECT_ID with the project ID of the project that you created.

  4. In Cloud Shell, create the Terraform plan file and convert it to JSON format:

    terraform plan -out main.plan
    terraform show -json main.plan > mainplan.json
    
  5. Create the IaC validation report for mainplan.json:

    gcloud scc iac-validation-reports create organizations/ORGANIZATION_ID/locations/global --tf-plan-file=mainplan.json
    

    This command returns an IaC validation report that describes the following violations:

    • The mtu for example_network isn't 1000.
    • The initial_node_count for example_node_pool isn't 3.
    • The example_bucket doesn't have uniform bucket level access enabled.
    • The example_bucket doesn't have logging enabled.

Resolve violations

  1. In Cloud Shell, launch the Cloud Shell Editor.

  2. Update the main.tf file with the following changes:

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
        }
      }
    }
    
    provider "google" {
      region  = "us-central1"
      zone    = "us-central1-c"
    }
    
    resource "google_compute_network" "example_network"{
      name                            = "example-network-1"
      delete_default_routes_on_create = false
      auto_create_subnetworks         = false
      routing_mode                    = "REGIONAL"
      mtu                             = 1000
      project                         = "PROJECT_ID"
    }
    
    resource "google_container_node_pool" "example_node_pool" {
      name               = "example-node-pool-1"
      cluster            = "example-cluster-1"
      project            = "PROJECT_ID"
      initial_node_count = 3
    
      node_config {
        preemptible  = true
        machine_type = "e2-medium"
      }
    }
    
    resource "google_storage_bucket" "example_bucket" {
      name          = "example-bucket-1"
      location      = "EU"
      force_destroy = true
    
      project = "PROJECT_ID"
      uniform_bucket_level_access = true
    
      logging {
        log_bucket   = "my-unique-logging-bucket" // Create a separate bucket for logs
        log_object_prefix = "tf-logs/"             // Optional prefix for better structure
      }
    }
    

    Replace PROJECT_ID with the project ID of the project that you created.

  3. In Cloud Shell, create the Terraform plan file and convert it to JSON format:

    terraform plan -out main.plan
    terraform show -json main.plan > mainplan.json
    
  4. Recreate the IaC validation report for mainplan.json:

    gcloud scc iac-validation-reports create organizations/ORGANIZATION_ID/locations/global --tf-plan-file=mainplan.json