# Cloud Compliance Scan Lab — Scan → Triage → Fix → Codify

> **Intro:** Compliance scans are most useful when they are treated as a **learning loop**, not as a compliance theatre exercise. This lab turns cloud posture findings into engineering practice: scan the environment, triage what matters, fix the root cause, and then codify the fix so the issue does not come back.
>
> **What this page includes**
>
> * a practical cloud-compliance lab flow;
> * CLI examples using Prowler, Checkov, and Cloud Custodian concepts;
> * how to move from a finding to a codified preventive control;
> * how to avoid false confidence from “green” compliance dashboards.

## Why this lab matters

This lab is not the highest-value pack in the entire KB, but it becomes very useful once teams start shipping cloud changes every week. It teaches:

* what cloud posture findings actually mean;
* how to separate **noise**, **true risk**, and **contextual exceptions**;
* how to drive fixes back into Terraform, policies, and platform defaults.

## The four-stage loop

### 1. Scan

Run posture or compliance checks against cloud accounts, subscriptions, projects, or IaC.

### 2. Triage

Decide which issues are:

* clearly exploitable or internet-exposed;
* risky but non-urgent;
* expected due to architecture or compensating controls;
* scanner noise.

### 3. Fix

Correct the misconfiguration in the resource **and** in the source of truth.

### 4. Codify

Prevent recurrence with:

* IaC changes;
* policy-as-code;
* CI checks;
* guardrails;
* runbooks.

## Suggested tool mix

| Stage                    | Useful tools    | Why                                                    |
| ------------------------ | --------------- | ------------------------------------------------------ |
| Scan live cloud          | Prowler         | Multi-cloud posture and compliance checks with reports |
| Scan IaC before deploy   | Checkov         | Fast misconfiguration feedback in PRs and CI           |
| Codify or auto-remediate | Cloud Custodian | YAML policies that filter resources and take action    |

## Example 1 — run a live cloud scan with Prowler

### AWS

```bash
prowler aws -M csv json-ocsf html
```

### Azure

```bash
prowler azure -M csv json-ocsf html
```

### GCP

```bash
prowler gcp -M csv json-ocsf html
```

### What to preserve

* raw report files;
* exact account or project scanned;
* tool version;
* time of scan;
* identity or role used to scan.

## Example 2 — scan IaC with Checkov before deployment

### Local directory scan

```bash
pip install checkov
checkov -d infra/
```

### GitHub Actions example

```yaml
name: iac-checkov
on:
  pull_request:
  push:
    branches: [main]

jobs:
  checkov:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Checkov
        uses: bridgecrewio/checkov-action@master
        with:
          directory: infra
          framework: terraform
```

## Example 3 — codify a fix with Terraform

### Insecure pattern

```hcl
resource "aws_s3_bucket" "app_data" {
  bucket = "demo-app-data"
}
```

### Better pattern

```hcl
resource "aws_s3_bucket" "app_data" {
  bucket = "demo-app-data"
}

resource "aws_s3_bucket_public_access_block" "app_data" {
  bucket                  = aws_s3_bucket.app_data.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}
```

## Example 4 — codify response logic with Cloud Custodian

### AWS example policy

```yaml
policies:
  - name: tag-public-s3-and-notify
    resource: aws.s3
    filters:
      - type: global-grants
    actions:
      - type: tag
        key: SecurityFinding
        value: PublicExposure
```

### Azure example policy skeleton

```yaml
policies:
  - name: tag-open-nsg
    resource: azure.networksecuritygroup
    filters:
      - type: ingress
        Ports: [22, 3389]
        Only: [0.0.0.0/0]
    actions:
      - type: tag
        tags:
          SecurityFinding: PublicAdminAccess
```

## Triage worksheet

| Question                                                  | Why it matters                                      |
| --------------------------------------------------------- | --------------------------------------------------- |
| Is the resource internet reachable?                       | Exposure beats abstract scorecards                  |
| Does the finding affect data, identity, or control plane? | Prioritizes business impact                         |
| Is there a compensating control?                          | Prevents wasted work                                |
| Can we fix it in source of truth?                         | Temporary console fixes drift back                  |
| Should this become a blocking CI control?                 | Converts one-off cleanup into a program improvement |

## Web UI flow idea

If you use Prowler App or another posture UI:

1. filter by provider and framework;
2. sort by high-severity internet exposure, identity issues, and logging gaps;
3. open the exact failed control;
4. capture the fix owner and source-of-truth location;
5. verify after remediation;
6. codify the change in Terraform, policy-as-code, or a platform baseline.

## Common mistakes

* closing the alert only in the cloud console;
* mixing compliance severity with exploitability;
* shipping a suppression before understanding the architecture;
* failing to encode the fix back into IaC or policy.

## Cross-links

* [Vendor Guides and Standards Map](/metrics-audit-risk-evidence-and-compliance/index-1/vendor-guides-and-standards-map.md)
* [Cloud Change Review Checklist](/learning-labs-interview-and-templates/index-3/cloud-change-review-checklist.md)
* [Policy Exception Governance Pack](/metrics-audit-risk-evidence-and-compliance/index/policy-exception-governance-pack.md)

\---*Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.*


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.product-security.expert/learning-labs-interview-and-templates/index-2/cloud-compliance-scan-lab-scan-triage-fix-codify.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
