From c25deccd21220833f1a5640633f0762673323dd0 Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 13:37:31 +0900 Subject: [PATCH 01/10] #41 checkov --- .github/workflows/checkov.yml | 102 ++++++++++++++++ example/checkov/terraform-base-rule.yaml | 20 ++++ example/network/result-checkov | 146 +++++++++++++++++++++++ example/network/result-trivy | 103 ++++++++++++++++ scripts/operations.yaml | 86 ++++++++++++- 5 files changed, 454 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/checkov.yml create mode 100644 example/checkov/terraform-base-rule.yaml create mode 100644 example/network/result-checkov create mode 100644 example/network/result-trivy diff --git a/.github/workflows/checkov.yml b/.github/workflows/checkov.yml new file mode 100644 index 0000000..c8d3bfb --- /dev/null +++ b/.github/workflows/checkov.yml @@ -0,0 +1,102 @@ +name: Checkov Security Scan + +on: + pull_request: + branches: [ main ] + push: + branches: [ 41-static-analysis ] + +jobs: + checkov: + runs-on: ubuntu-latest + name: checkov-action + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Run Checkov action + id: checkov + uses: bridgecrewio/checkov-action@master + with: + directory: ./example/actions/terraform + framework: terraform + # Scan Terraform files in codes/ directory + # Scan Kubernetes manifests in codes/*/k8s/ directories + # Use custom policies from codes/checkov/ + check: CKV_AWS_* + external_checks_dirs: ./example/checkov + output_format: sarif + output_file_path: reports/results.sarif + download_external_modules: true + log_level: INFO + + - name: Upload SARIF file + if: always() + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: reports/results.sarif + + - name: Comment PR with results + if: github.event_name == 'pull_request' && (success() || failure()) + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = require('path'); + + // Read SARIF results if available + let comment = '## Checkov Security Scan Results\n\n'; + + try { + if (fs.existsSync('reports/results.sarif')) { + const sarif = JSON.parse(fs.readFileSync('reports/results.sarif', 'utf8')); + const runs = sarif.runs || []; + + for (const run of runs) { + const results = run.results || []; + comment += `### ${run.tool.driver.name}\n`; + comment += `- Total issues found: ${results.length}\n`; + + const failedResults = results.filter(r => r.level === 'error'); + const warningResults = results.filter(r => r.level === 'warning'); + + comment += `- Failed checks: ${failedResults.length}\n`; + comment += `- Warning checks: ${warningResults.length}\n\n`; + + if (failedResults.length > 0) { + comment += '#### Failed Checks:\n'; + for (const result of failedResults.slice(0, 10)) { // Limit to first 10 + const location = result.locations?.[0]?.physicalLocation; + const file = location?.artifactLocation?.uri || 'Unknown'; + const line = location?.region?.startLine || 'N/A'; + comment += `- **${result.ruleId}**: ${result.message.text} (${file}:${line})\n`; + } + if (failedResults.length > 10) { + comment += `\n... and ${failedResults.length - 10} more issues.\n`; + } + } + } + } else { + comment += 'No SARIF results file found.\n'; + } + } catch (error) { + comment += `Error reading results: ${error.message}\n`; + } + + // Add workflow status + comment += `\n### Workflow Status\n`; + comment += `- Job status: ${{ job.status }}\n`; + comment += `- Checkov step status: ${{ steps.checkov.outcome }}\n`; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); + + - name: Fail if Checkov found issues + if: steps.checkov.outcome == 'failure' + run: | + echo "Checkov found security or policy violations. Please review and fix them." + exit 1 \ No newline at end of file diff --git a/example/checkov/terraform-base-rule.yaml b/example/checkov/terraform-base-rule.yaml new file mode 100644 index 0000000..ca9be69 --- /dev/null +++ b/example/checkov/terraform-base-rule.yaml @@ -0,0 +1,20 @@ +--- +metadata: + id: "TERRAFORM_AWS_PROVIDER_CHECK" + name: "Check the tags and regions" + category: "CONVENTION" +scope: + provider: "AWS" +definition: + and: + - cond_type: "attribute" + resource_types: + - "provider" + attribute: "default_tags.tags.owner" + operator: exists + - cond_type: "attribute" + resource_types: + - "provider" + attribute: "region" + operator: "equals" + value: "ap-northeast-2" \ No newline at end of file diff --git a/example/network/result-checkov b/example/network/result-checkov new file mode 100644 index 0000000..13ff3ba --- /dev/null +++ b/example/network/result-checkov @@ -0,0 +1,146 @@ + + _ _ + ___| |__ ___ ___| | _______ __ + / __| '_ \ / _ \/ __| |/ / _ \ \ / / + | (__| | | | __/ (__| < (_) \ V / + \___|_| |_|\___|\___|_|\_\___/ \_/ + +By Prisma Cloud | version: 3.2.457 + +terraform scan results: + +Passed checks: 8, Failed checks: 6, Skipped checks: 0 + +Check: CKV_AWS_41: "Ensure no hard coded AWS access key and secret key exists in provider" + PASSED for resource: aws.default + File: /_versions.tf:20-28 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/secrets-policies/bc-aws-secrets-5 +Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" + PASSED for resource: aws_subnet.private["a"] + File: /subnet.tf:15-26 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default +Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" + PASSED for resource: aws_subnet.private["b"] + File: /subnet.tf:15-26 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default +Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" + PASSED for resource: aws_subnet.private["c"] + File: /subnet.tf:15-26 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default +Check: CKV2_AWS_44: "Ensure AWS route table with VPC peering does not contain routes overly permissive to all traffic" + PASSED for resource: aws_route_table.public + File: /routetable.tf:1-12 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-aws-route-table-with-vpc-peering-does-not-contain-routes-overly-permissive-to-all-traffic +Check: CKV2_AWS_44: "Ensure AWS route table with VPC peering does not contain routes overly permissive to all traffic" + PASSED for resource: aws_route_table.private + File: /routetable.tf:21-32 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-aws-route-table-with-vpc-peering-does-not-contain-routes-overly-permissive-to-all-traffic +Check: CKV2_AWS_35: "AWS NAT Gateways should be utilized for the default route" + PASSED for resource: aws_route_table.public + File: /routetable.tf:1-12 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-aws-nat-gateways-are-utilized-for-the-default-route +Check: CKV2_AWS_35: "AWS NAT Gateways should be utilized for the default route" + PASSED for resource: aws_route_table.private + File: /routetable.tf:21-32 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-aws-nat-gateways-are-utilized-for-the-default-route +Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" + FAILED for resource: aws_subnet.public["a"] + File: /subnet.tf:1-13 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default + + 1 | resource "aws_subnet" "public" { + 2 | for_each = local.public_subnets + 3 | + 4 | vpc_id = aws_vpc.this.id + 5 | availability_zone = "${local.region}${each.key}" + 6 | cidr_block = each.value + 7 | map_public_ip_on_launch = true + 8 | + 9 | tags = { + 10 | Name = "${local.name_prefix}-public-${each.key}", + 11 | "kubernetes.io/role/elb" = "1" + 12 | } + 13 | } + +Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" + FAILED for resource: aws_subnet.public["b"] + File: /subnet.tf:1-13 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default + + 1 | resource "aws_subnet" "public" { + 2 | for_each = local.public_subnets + 3 | + 4 | vpc_id = aws_vpc.this.id + 5 | availability_zone = "${local.region}${each.key}" + 6 | cidr_block = each.value + 7 | map_public_ip_on_launch = true + 8 | + 9 | tags = { + 10 | Name = "${local.name_prefix}-public-${each.key}", + 11 | "kubernetes.io/role/elb" = "1" + 12 | } + 13 | } + +Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" + FAILED for resource: aws_subnet.public["c"] + File: /subnet.tf:1-13 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default + + 1 | resource "aws_subnet" "public" { + 2 | for_each = local.public_subnets + 3 | + 4 | vpc_id = aws_vpc.this.id + 5 | availability_zone = "${local.region}${each.key}" + 6 | cidr_block = each.value + 7 | map_public_ip_on_launch = true + 8 | + 9 | tags = { + 10 | Name = "${local.name_prefix}-public-${each.key}", + 11 | "kubernetes.io/role/elb" = "1" + 12 | } + 13 | } + +Check: CKV2_AWS_11: "Ensure VPC flow logging is enabled in all VPCs" + FAILED for resource: aws_vpc.this + File: /vpc.tf:1-9 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-logging-policies/logging-9-enable-vpc-flow-logging + + 1 | resource "aws_vpc" "this" { + 2 | cidr_block = local.vpc_cidr + 3 | enable_dns_support = true + 4 | enable_dns_hostnames = true + 5 | + 6 | tags = { + 7 | Name = local.name_prefix + 8 | } + 9 | } + +Check: CKV2_AWS_12: "Ensure the default security group of every VPC restricts all traffic" + FAILED for resource: aws_vpc.this + File: /vpc.tf:1-9 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/networking-4 + + 1 | resource "aws_vpc" "this" { + 2 | cidr_block = local.vpc_cidr + 3 | enable_dns_support = true + 4 | enable_dns_hostnames = true + 5 | + 6 | tags = { + 7 | Name = local.name_prefix + 8 | } + 9 | } + +Check: CKV2_AWS_19: "Ensure that all EIP addresses allocated to a VPC are attached to EC2 instances" + FAILED for resource: aws_eip.nat + File: /natgw.tf:1-7 + Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-that-all-eip-addresses-allocated-to-a-vpc-are-attached-to-ec2-instances + + 1 | resource "aws_eip" "nat" { + 2 | depends_on = [aws_internet_gateway.this] + 3 | + 4 | tags = { + 5 | Name = "${local.name_prefix}-natgw" + 6 | } + 7 | } + + diff --git a/example/network/result-trivy b/example/network/result-trivy new file mode 100644 index 0000000..9f23fca --- /dev/null +++ b/example/network/result-trivy @@ -0,0 +1,103 @@ + +Report Summary + +┌───────────┬───────────┬───────────────────┐ +│ Target │ Type │ Misconfigurations │ +├───────────┼───────────┼───────────────────┤ +│ . │ terraform │ 0 │ +├───────────┼───────────┼───────────────────┤ +│ subnet.tf │ terraform │ 3 │ +├───────────┼───────────┼───────────────────┤ +│ vpc.tf │ terraform │ 1 │ +└───────────┴───────────┴───────────────────┘ +Legend: +- '-': Not scanned +- '0': Clean (no security findings detected) + + +subnet.tf (terraform) +===================== +Tests: 3 (SUCCESSES: 0, FAILURES: 3) +Failures: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 3, CRITICAL: 0) + +AVD-AWS-0164 (HIGH): Subnet associates public IP address. +════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ +You should limit the provision of public IP addresses for resources. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application. + + +See https://avd.aquasec.com/misconfig/aws-vpc-no-public-ingress-sgr +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + subnet.tf:7 + via subnet.tf:1-13 (aws_subnet.public["a"]) +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + 1 resource "aws_subnet" "public" { + . + 7 [ map_public_ip_on_launch = true + .. + 13 } +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + +AVD-AWS-0164 (HIGH): Subnet associates public IP address. +════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ +You should limit the provision of public IP addresses for resources. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application. + + +See https://avd.aquasec.com/misconfig/aws-vpc-no-public-ingress-sgr +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + subnet.tf:7 + via subnet.tf:1-13 (aws_subnet.public["b"]) +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + 1 resource "aws_subnet" "public" { + . + 7 [ map_public_ip_on_launch = true + .. + 13 } +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + +AVD-AWS-0164 (HIGH): Subnet associates public IP address. +════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ +You should limit the provision of public IP addresses for resources. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application. + + +See https://avd.aquasec.com/misconfig/aws-vpc-no-public-ingress-sgr +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + subnet.tf:7 + via subnet.tf:1-13 (aws_subnet.public["c"]) +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + 1 resource "aws_subnet" "public" { + . + 7 [ map_public_ip_on_launch = true + .. + 13 } +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + +vpc.tf (terraform) +================== +Tests: 1 (SUCCESSES: 0, FAILURES: 1) +Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) + +AVD-AWS-0178 (MEDIUM): VPC does not have VPC Flow Logs enabled. +════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ +VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows. + + +See https://avd.aquasec.com/misconfig/aws-autoscaling-enable-at-rest-encryption +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + vpc.tf:1-9 +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + 1 ┌ resource "aws_vpc" "this" { + 2 │ cidr_block = local.vpc_cidr + 3 │ enable_dns_support = true + 4 │ enable_dns_hostnames = true + 5 │ + 6 │ tags = { + 7 │ Name = local.name_prefix + 8 │ } + 9 └ } +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + diff --git a/scripts/operations.yaml b/scripts/operations.yaml index 30ff7e7..daa0747 100644 --- a/scripts/operations.yaml +++ b/scripts/operations.yaml @@ -1,10 +1,90 @@ issues: - title: checkovによるポリシーチェック body: | - hoge - - title: trivyによるセキュリティスキャン + プロジェクト独自のルールや規約(命名規則、タグ付けルール、リージョン制約など)を自動的に検査し、遵守を確保することは重要です。ポリシーチェックツールを使用することで、これらのプロジェクト固有のルールとセキュリティベストプラクティスの両方を自動検査し、コードの品質とセキュリティを向上させることができます。 + + # ポリシーチェックの必要性 + - プロジェクト固有のルール(命名規則、タグ付け、リージョン制約)の遵守確認が必要 + - 複数開発者による一貫した設定の維持とコードの統一性の確保 + - 手動によるルール確認は時間がかかり、見落としやヒューマンエラーが発生しやすい + + # 解決策 + - **Checkov**: YAMLベースの直感的なカスタムポリシー定義、TerraformとKubernetes両対応(本プラクティス採用) + - **Trivy**: 高速実行、統合セキュリティスキャナー、カスタムポリシーはOPA/Regoが必要 + - **Terrascan**: OPA/Regoベース、柔軟だが学習コストが高い + - **KICS**: 独自のクエリ言語、カスタムポリシー作成が複雑 + + 本プラクティスではYAMLでのカスタムポリシー定義が容易で、TerraformとKubernetesの両方に対して統一的なポリシー管理が可能なCheckovを採用します。 + + # Checkovによるポリシーチェック + - Checkovは1000以上のセキュリティ・コンプライアンスチェックを内蔵 + - Terraform、Kubernetes、Docker、CloudFormationなど多様な形式をサポート + - カスタムポリシーの作成により組織固有のルールを適用可能 + - JSON、SARIF、JUnit形式での結果出力によりCI/CD統合が容易 + + ## Checkovのインストールと基本的な使い方 + + - [Quick Start - checkov](https://www.checkov.io/1.Welcome/Quick%20Start.html) + + ## 主要なチェック項目 + + - [kubernetes resource scans - checkov](https://www.checkov.io/5.Policy%20Index/kubernetes.html) + - [terraform resource scans - checkov](https://www.checkov.io/5.Policy%20Index/terraform.html) + + ## カスタムポリシーの作成 + + [Custom Policies Overview - checkov](https://www.checkov.io/3.Custom%20Policies/Custom%20Policies%20Overview.html) + + # プラクティス + + ## 基本的なCheckovスキャン + - カスタムポリシーを定義し、プロジェクトのルールを自動検査 + - 今回はあえてチェックに`失敗`するようなポリシーを定義(作成したポリシーを別のissueで使います。) + - codes/checkovディレクトリを作成 + - ディレクトリ内にカスタムポリシーのYAMLを作成 + - TerraformのAWSプロバイダーにdefault_regionが`us-west-1`である事を確認するポリシー例 + - 作成したポリシーを使いcheckovを実行しカスタムポリシーの確認結果が`FAILED`になることを確認 + - title: CheckovによるポリシーチェックをCIに組み込む body: | - hoge + CI/CDパイプラインにポリシーチェックを統合することで、開発者が変更をプッシュする度に自動的にセキュリティとコンプライアンスの検証を行い、問題のあるコードが本番環境にデプロイされることを防げます。 + + # CI統合の必要性 + - 開発者の手動実行に依存すると、ポリシーチェックが忘れられる可能性がある + - プルリクエスト時点での自動検証により、早期に問題を発見・修正できる + - 継続的なセキュリティとコンプライアンスの維持が可能になる + - チーム全体での一貫したポリシー適用の強制ができる + + # 解決策 + - **GitHub Actions**: 無料プラン利用可能、Checkovの公式アクションあり、設定が簡単(本プラクティス採用) + - **GitLab CI**: GitLab利用時の選択肢、Dockerイメージでの実行 + - **Jenkins**: 自前構築が必要、柔軟性が高い + - **CircleCI**: 有料プラン必要、高性能な実行環境 + + 本プラクティスではGitHub Actionsを使用し、プルリクエスト時に自動的にCheckovスキャンを実行する仕組みを構築します。 + + # GitHub ActionsでのCheckov統合 + - Checkovには公式のGitHub Actionが提供されている + - プルリクエスト作成時およびコードプッシュ時に自動実行 + - 結果をプルリクエストのコメントに表示可能 + - 失敗時のワークフロー停止により問題のあるマージを防止 + + # プラクティス + + ## CI統合のためのワークフロー作成 + - `.github/workflows/`ディレクトリに`checkov.yml`ワークフローファイルを作成 + - プルリクエストをトリガーとしてCheckovスキャンを実行する設定 + - 以下の要件を満たすワークフローを作成: + - `pull_request`および`push` (mainブランチ)でトリガー + - Terraformファイル(`codes/`ディレクトリ)をスキャン + - Kubernetesマニフェスト(`codes/*/k8s/`ディレクトリ)をスキャン + - カスタムポリシー(`codes/checkov/`)を使用 + - 結果をプルリクエストコメントまたはチェック結果に表示 + + ## ワークフローのテスト + - 新しいブランチを作成し、故意にポリシー違反のあるTerraformコードを追加 + - プルリクエストを作成し、Checkovワークフローが自動実行されることを確認 + - ワークフローの実行結果とプルリクエストへのフィードバックを確認 + - title: AtlantisによるPRベースのterraform plan/apply body: | hoge From ba2d3547815954ad69b467939c96173b9cfec071 Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 13:40:44 +0900 Subject: [PATCH 02/10] #41 checkov --- example/checkov/terraform-base-rule.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/checkov/terraform-base-rule.yaml b/example/checkov/terraform-base-rule.yaml index ca9be69..002093d 100644 --- a/example/checkov/terraform-base-rule.yaml +++ b/example/checkov/terraform-base-rule.yaml @@ -17,4 +17,4 @@ definition: - "provider" attribute: "region" operator: "equals" - value: "ap-northeast-2" \ No newline at end of file + value: "ap-northeast-1" \ No newline at end of file From a3058b3c0a61670980062237a9cddded84c0c028 Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 13:44:59 +0900 Subject: [PATCH 03/10] #41 checkov --- .github/workflows/checkov.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/checkov.yml b/.github/workflows/checkov.yml index c8d3bfb..e576fcf 100644 --- a/.github/workflows/checkov.yml +++ b/.github/workflows/checkov.yml @@ -3,8 +3,6 @@ name: Checkov Security Scan on: pull_request: branches: [ main ] - push: - branches: [ 41-static-analysis ] jobs: checkov: @@ -24,7 +22,7 @@ jobs: # Scan Kubernetes manifests in codes/*/k8s/ directories # Use custom policies from codes/checkov/ check: CKV_AWS_* - external_checks_dirs: ./example/checkov + external_checks_dirs: ./example/checkov/ output_format: sarif output_file_path: reports/results.sarif download_external_modules: true From 394d42469ae3916e2542cd1aaf04a1f74becbc2a Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 13:49:18 +0900 Subject: [PATCH 04/10] #41 checkov --- .github/workflows/checkov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checkov.yml b/.github/workflows/checkov.yml index e576fcf..a6b8573 100644 --- a/.github/workflows/checkov.yml +++ b/.github/workflows/checkov.yml @@ -22,7 +22,7 @@ jobs: # Scan Kubernetes manifests in codes/*/k8s/ directories # Use custom policies from codes/checkov/ check: CKV_AWS_* - external_checks_dirs: ./example/checkov/ + external_checks_dirs: ../../checkov/ output_format: sarif output_file_path: reports/results.sarif download_external_modules: true From 72ce137b0d5f965da9ab991faf8ea9a1399fa7cc Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 13:55:08 +0900 Subject: [PATCH 05/10] #41 checkov --- .github/workflows/checkov.yml | 4 ++-- example/checkov/terraform-base-rule.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/checkov.yml b/.github/workflows/checkov.yml index a6b8573..009a157 100644 --- a/.github/workflows/checkov.yml +++ b/.github/workflows/checkov.yml @@ -21,8 +21,8 @@ jobs: # Scan Terraform files in codes/ directory # Scan Kubernetes manifests in codes/*/k8s/ directories # Use custom policies from codes/checkov/ - check: CKV_AWS_* - external_checks_dirs: ../../checkov/ + check: CUSTOM_* + external_checks_dirs: ./example/checkov/ output_format: sarif output_file_path: reports/results.sarif download_external_modules: true diff --git a/example/checkov/terraform-base-rule.yaml b/example/checkov/terraform-base-rule.yaml index 002093d..25c712c 100644 --- a/example/checkov/terraform-base-rule.yaml +++ b/example/checkov/terraform-base-rule.yaml @@ -1,6 +1,6 @@ --- metadata: - id: "TERRAFORM_AWS_PROVIDER_CHECK" + id: "CUSTOM_AWS_PROVIDER_CHECK" name: "Check the tags and regions" category: "CONVENTION" scope: From 2e4df1bbc132cc9b1ebca7a5628f4594027ae2ce Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 14:18:58 +0900 Subject: [PATCH 06/10] #41 checkov --- .github/workflows/checkov.yml | 78 ----------------------------------- 1 file changed, 78 deletions(-) diff --git a/.github/workflows/checkov.yml b/.github/workflows/checkov.yml index 009a157..7552b4d 100644 --- a/.github/workflows/checkov.yml +++ b/.github/workflows/checkov.yml @@ -18,83 +18,5 @@ jobs: with: directory: ./example/actions/terraform framework: terraform - # Scan Terraform files in codes/ directory - # Scan Kubernetes manifests in codes/*/k8s/ directories - # Use custom policies from codes/checkov/ check: CUSTOM_* external_checks_dirs: ./example/checkov/ - output_format: sarif - output_file_path: reports/results.sarif - download_external_modules: true - log_level: INFO - - - name: Upload SARIF file - if: always() - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: reports/results.sarif - - - name: Comment PR with results - if: github.event_name == 'pull_request' && (success() || failure()) - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const path = require('path'); - - // Read SARIF results if available - let comment = '## Checkov Security Scan Results\n\n'; - - try { - if (fs.existsSync('reports/results.sarif')) { - const sarif = JSON.parse(fs.readFileSync('reports/results.sarif', 'utf8')); - const runs = sarif.runs || []; - - for (const run of runs) { - const results = run.results || []; - comment += `### ${run.tool.driver.name}\n`; - comment += `- Total issues found: ${results.length}\n`; - - const failedResults = results.filter(r => r.level === 'error'); - const warningResults = results.filter(r => r.level === 'warning'); - - comment += `- Failed checks: ${failedResults.length}\n`; - comment += `- Warning checks: ${warningResults.length}\n\n`; - - if (failedResults.length > 0) { - comment += '#### Failed Checks:\n'; - for (const result of failedResults.slice(0, 10)) { // Limit to first 10 - const location = result.locations?.[0]?.physicalLocation; - const file = location?.artifactLocation?.uri || 'Unknown'; - const line = location?.region?.startLine || 'N/A'; - comment += `- **${result.ruleId}**: ${result.message.text} (${file}:${line})\n`; - } - if (failedResults.length > 10) { - comment += `\n... and ${failedResults.length - 10} more issues.\n`; - } - } - } - } else { - comment += 'No SARIF results file found.\n'; - } - } catch (error) { - comment += `Error reading results: ${error.message}\n`; - } - - // Add workflow status - comment += `\n### Workflow Status\n`; - comment += `- Job status: ${{ job.status }}\n`; - comment += `- Checkov step status: ${{ steps.checkov.outcome }}\n`; - - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: comment - }); - - - name: Fail if Checkov found issues - if: steps.checkov.outcome == 'failure' - run: | - echo "Checkov found security or policy violations. Please review and fix them." - exit 1 \ No newline at end of file From 78c99d1b1a89c0583666a4b8527e4953ce628640 Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 14:21:49 +0900 Subject: [PATCH 07/10] #41 checkov --- example/checkov/terraform-base-rule.yaml | 2 +- scripts/operations.yaml | 34 +++++++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/example/checkov/terraform-base-rule.yaml b/example/checkov/terraform-base-rule.yaml index 25c712c..351beee 100644 --- a/example/checkov/terraform-base-rule.yaml +++ b/example/checkov/terraform-base-rule.yaml @@ -17,4 +17,4 @@ definition: - "provider" attribute: "region" operator: "equals" - value: "ap-northeast-1" \ No newline at end of file + value: "ap-northeast-2" \ No newline at end of file diff --git a/scripts/operations.yaml b/scripts/operations.yaml index daa0747..2ed7cf6 100644 --- a/scripts/operations.yaml +++ b/scripts/operations.yaml @@ -38,12 +38,16 @@ issues: # プラクティス ## 基本的なCheckovスキャン + - checkovをローカル端末にインストール - カスタムポリシーを定義し、プロジェクトのルールを自動検査 - 今回はあえてチェックに`失敗`するようなポリシーを定義(作成したポリシーを別のissueで使います。) - codes/checkovディレクトリを作成 - ディレクトリ内にカスタムポリシーのYAMLを作成 - - TerraformのAWSプロバイダーにdefault_regionが`us-west-1`である事を確認するポリシー例 + - ポリシーのIDは`CUSTOM_AWS_PROVIDER_CHECK`にする + - TerraformのAWSプロバイダーにdefault_regionが`us-west-1`である事を確認 - 作成したポリシーを使いcheckovを実行しカスタムポリシーの確認結果が`FAILED`になることを確認 + - 対象は`codes/actions/terraform`ディレクトリなど任意 + - `--chekc "CUSTOM_*"`を付けるとカスタムポリシーのみチェックできる - title: CheckovによるポリシーチェックをCIに組み込む body: | CI/CDパイプラインにポリシーチェックを統合することで、開発者が変更をプッシュする度に自動的にセキュリティとコンプライアンスの検証を行い、問題のあるコードが本番環境にデプロイされることを防げます。 @@ -70,20 +74,30 @@ issues: # プラクティス + ## 前提 + + - checkovによるポリシーチェック のissueを完了していること + ## CI統合のためのワークフロー作成 - `.github/workflows/`ディレクトリに`checkov.yml`ワークフローファイルを作成 - - プルリクエストをトリガーとしてCheckovスキャンを実行する設定 - - 以下の要件を満たすワークフローを作成: - - `pull_request`および`push` (mainブランチ)でトリガー - - Terraformファイル(`codes/`ディレクトリ)をスキャン - - Kubernetesマニフェスト(`codes/*/k8s/`ディレクトリ)をスキャン + - mainへのプルリクエストをトリガーとしてワークフローを実行 + - [checkov-action](https://github.com/bridgecrewio/checkov-action)を参考にcheckovを実行 + - Terraformディレクトリ(`codes/actions/terraform`等)をスキャン + - フレームワークは`terraform` - カスタムポリシー(`codes/checkov/`)を使用 - - 結果をプルリクエストコメントまたはチェック結果に表示 + - チェックは`CUSTOM_*`のみ ## ワークフローのテスト - - 新しいブランチを作成し、故意にポリシー違反のあるTerraformコードを追加 - - プルリクエストを作成し、Checkovワークフローが自動実行されることを確認 - - ワークフローの実行結果とプルリクエストへのフィードバックを確認 + - 作業ブランチをリモートにプッシュしPRを作成 + - GitHub Actionsでチェックが自動で行われ**失敗**することを確認 + - `codes/checkov`配下のポリシーを修正しリモートに再プッシュ + - GitHub Actionsでチェックが自動で行われ**成功**することを確認 + + ## 更に発展的なプラクティス + このプラクティスは余裕がなければやらなくてもいいです。 + + - 対象ディレクトリをハードコードではなく変更のあったTerraformディレクトリにする + - チェック結果をPRのコメントに表示する - title: AtlantisによるPRベースのterraform plan/apply body: | From 0471c6ab98b8fc0410faa923a362086c984dd695 Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 14:27:08 +0900 Subject: [PATCH 08/10] #41 checkov --- .github/workflows/checkov.yml | 23 ++++++++++++++++++++++- example/ecr/_versions.tf | 3 ++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/checkov.yml b/.github/workflows/checkov.yml index 7552b4d..258e5a7 100644 --- a/.github/workflows/checkov.yml +++ b/.github/workflows/checkov.yml @@ -11,12 +11,33 @@ jobs: steps: - name: Checkout repo uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get changed Terraform directories + id: changed-dirs + run: | + # Get changed .tf files in the PR + changed_files=$(git diff --name-only origin/main...HEAD | grep '\.tf$' || true) + + if [ -z "$changed_files" ]; then + echo "No Terraform files changed" + echo "has_changes=false" >> $GITHUB_OUTPUT + exit 0 + fi + + # Extract unique directories containing .tf files + directories=$(echo "$changed_files" | xargs dirname | sort -u | tr '\n' ',' | sed 's/,$//') + echo "directories=$directories" >> $GITHUB_OUTPUT + echo "has_changes=true" >> $GITHUB_OUTPUT + echo "Changed Terraform directories: $directories" - name: Run Checkov action + if: steps.changed-dirs.outputs.has_changes == 'true' id: checkov uses: bridgecrewio/checkov-action@master with: - directory: ./example/actions/terraform + directory: ${{ steps.changed-dirs.outputs.directories }} framework: terraform check: CUSTOM_* external_checks_dirs: ./example/checkov/ diff --git a/example/ecr/_versions.tf b/example/ecr/_versions.tf index 96f1a3a..088cdfc 100644 --- a/example/ecr/_versions.tf +++ b/example/ecr/_versions.tf @@ -22,7 +22,8 @@ provider "aws" { default_tags { tags = { project = "cn-practice", - owner = "mori" + owner = "mori", + test = "checkov" } } } From fe820383539735c273cd201a59687df781ec95cd Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 14:50:23 +0900 Subject: [PATCH 09/10] =?UTF-8?q?#41=20checkov=E3=81=AB=E3=82=88=E3=82=8B?= =?UTF-8?q?=E3=83=9D=E3=83=AA=E3=82=B7=E3=83=BC=E3=83=81=E3=82=A7=E3=83=83?= =?UTF-8?q?=E3=82=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- {.github/workflows => example/actions/github}/checkov.yml | 0 example/ecr/_versions.tf | 3 +-- scripts/operations.yaml | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) rename {.github/workflows => example/actions/github}/checkov.yml (100%) diff --git a/.github/workflows/checkov.yml b/example/actions/github/checkov.yml similarity index 100% rename from .github/workflows/checkov.yml rename to example/actions/github/checkov.yml diff --git a/example/ecr/_versions.tf b/example/ecr/_versions.tf index 088cdfc..96f1a3a 100644 --- a/example/ecr/_versions.tf +++ b/example/ecr/_versions.tf @@ -22,8 +22,7 @@ provider "aws" { default_tags { tags = { project = "cn-practice", - owner = "mori", - test = "checkov" + owner = "mori" } } } diff --git a/scripts/operations.yaml b/scripts/operations.yaml index 2ed7cf6..a457b82 100644 --- a/scripts/operations.yaml +++ b/scripts/operations.yaml @@ -97,7 +97,6 @@ issues: このプラクティスは余裕がなければやらなくてもいいです。 - 対象ディレクトリをハードコードではなく変更のあったTerraformディレクトリにする - - チェック結果をPRのコメントに表示する - title: AtlantisによるPRベースのterraform plan/apply body: | From df6646ba561a8d4821f6b5d062c115b500813770 Mon Sep 17 00:00:00 2001 From: Ryota Mori Date: Fri, 1 Aug 2025 14:51:22 +0900 Subject: [PATCH 10/10] =?UTF-8?q?#41=20checkov=E3=81=AB=E3=82=88=E3=82=8B?= =?UTF-8?q?=E3=83=9D=E3=83=AA=E3=82=B7=E3=83=BC=E3=83=81=E3=82=A7=E3=83=83?= =?UTF-8?q?=E3=82=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/network/result-checkov | 146 --------------------------------- example/network/result-trivy | 103 ----------------------- 2 files changed, 249 deletions(-) delete mode 100644 example/network/result-checkov delete mode 100644 example/network/result-trivy diff --git a/example/network/result-checkov b/example/network/result-checkov deleted file mode 100644 index 13ff3ba..0000000 --- a/example/network/result-checkov +++ /dev/null @@ -1,146 +0,0 @@ - - _ _ - ___| |__ ___ ___| | _______ __ - / __| '_ \ / _ \/ __| |/ / _ \ \ / / - | (__| | | | __/ (__| < (_) \ V / - \___|_| |_|\___|\___|_|\_\___/ \_/ - -By Prisma Cloud | version: 3.2.457 - -terraform scan results: - -Passed checks: 8, Failed checks: 6, Skipped checks: 0 - -Check: CKV_AWS_41: "Ensure no hard coded AWS access key and secret key exists in provider" - PASSED for resource: aws.default - File: /_versions.tf:20-28 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/secrets-policies/bc-aws-secrets-5 -Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" - PASSED for resource: aws_subnet.private["a"] - File: /subnet.tf:15-26 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default -Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" - PASSED for resource: aws_subnet.private["b"] - File: /subnet.tf:15-26 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default -Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" - PASSED for resource: aws_subnet.private["c"] - File: /subnet.tf:15-26 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default -Check: CKV2_AWS_44: "Ensure AWS route table with VPC peering does not contain routes overly permissive to all traffic" - PASSED for resource: aws_route_table.public - File: /routetable.tf:1-12 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-aws-route-table-with-vpc-peering-does-not-contain-routes-overly-permissive-to-all-traffic -Check: CKV2_AWS_44: "Ensure AWS route table with VPC peering does not contain routes overly permissive to all traffic" - PASSED for resource: aws_route_table.private - File: /routetable.tf:21-32 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-aws-route-table-with-vpc-peering-does-not-contain-routes-overly-permissive-to-all-traffic -Check: CKV2_AWS_35: "AWS NAT Gateways should be utilized for the default route" - PASSED for resource: aws_route_table.public - File: /routetable.tf:1-12 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-aws-nat-gateways-are-utilized-for-the-default-route -Check: CKV2_AWS_35: "AWS NAT Gateways should be utilized for the default route" - PASSED for resource: aws_route_table.private - File: /routetable.tf:21-32 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-aws-nat-gateways-are-utilized-for-the-default-route -Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" - FAILED for resource: aws_subnet.public["a"] - File: /subnet.tf:1-13 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default - - 1 | resource "aws_subnet" "public" { - 2 | for_each = local.public_subnets - 3 | - 4 | vpc_id = aws_vpc.this.id - 5 | availability_zone = "${local.region}${each.key}" - 6 | cidr_block = each.value - 7 | map_public_ip_on_launch = true - 8 | - 9 | tags = { - 10 | Name = "${local.name_prefix}-public-${each.key}", - 11 | "kubernetes.io/role/elb" = "1" - 12 | } - 13 | } - -Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" - FAILED for resource: aws_subnet.public["b"] - File: /subnet.tf:1-13 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default - - 1 | resource "aws_subnet" "public" { - 2 | for_each = local.public_subnets - 3 | - 4 | vpc_id = aws_vpc.this.id - 5 | availability_zone = "${local.region}${each.key}" - 6 | cidr_block = each.value - 7 | map_public_ip_on_launch = true - 8 | - 9 | tags = { - 10 | Name = "${local.name_prefix}-public-${each.key}", - 11 | "kubernetes.io/role/elb" = "1" - 12 | } - 13 | } - -Check: CKV_AWS_130: "Ensure VPC subnets do not assign public IP by default" - FAILED for resource: aws_subnet.public["c"] - File: /subnet.tf:1-13 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-vpc-subnets-do-not-assign-public-ip-by-default - - 1 | resource "aws_subnet" "public" { - 2 | for_each = local.public_subnets - 3 | - 4 | vpc_id = aws_vpc.this.id - 5 | availability_zone = "${local.region}${each.key}" - 6 | cidr_block = each.value - 7 | map_public_ip_on_launch = true - 8 | - 9 | tags = { - 10 | Name = "${local.name_prefix}-public-${each.key}", - 11 | "kubernetes.io/role/elb" = "1" - 12 | } - 13 | } - -Check: CKV2_AWS_11: "Ensure VPC flow logging is enabled in all VPCs" - FAILED for resource: aws_vpc.this - File: /vpc.tf:1-9 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-logging-policies/logging-9-enable-vpc-flow-logging - - 1 | resource "aws_vpc" "this" { - 2 | cidr_block = local.vpc_cidr - 3 | enable_dns_support = true - 4 | enable_dns_hostnames = true - 5 | - 6 | tags = { - 7 | Name = local.name_prefix - 8 | } - 9 | } - -Check: CKV2_AWS_12: "Ensure the default security group of every VPC restricts all traffic" - FAILED for resource: aws_vpc.this - File: /vpc.tf:1-9 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/networking-4 - - 1 | resource "aws_vpc" "this" { - 2 | cidr_block = local.vpc_cidr - 3 | enable_dns_support = true - 4 | enable_dns_hostnames = true - 5 | - 6 | tags = { - 7 | Name = local.name_prefix - 8 | } - 9 | } - -Check: CKV2_AWS_19: "Ensure that all EIP addresses allocated to a VPC are attached to EC2 instances" - FAILED for resource: aws_eip.nat - File: /natgw.tf:1-7 - Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-networking-policies/ensure-that-all-eip-addresses-allocated-to-a-vpc-are-attached-to-ec2-instances - - 1 | resource "aws_eip" "nat" { - 2 | depends_on = [aws_internet_gateway.this] - 3 | - 4 | tags = { - 5 | Name = "${local.name_prefix}-natgw" - 6 | } - 7 | } - - diff --git a/example/network/result-trivy b/example/network/result-trivy deleted file mode 100644 index 9f23fca..0000000 --- a/example/network/result-trivy +++ /dev/null @@ -1,103 +0,0 @@ - -Report Summary - -┌───────────┬───────────┬───────────────────┐ -│ Target │ Type │ Misconfigurations │ -├───────────┼───────────┼───────────────────┤ -│ . │ terraform │ 0 │ -├───────────┼───────────┼───────────────────┤ -│ subnet.tf │ terraform │ 3 │ -├───────────┼───────────┼───────────────────┤ -│ vpc.tf │ terraform │ 1 │ -└───────────┴───────────┴───────────────────┘ -Legend: -- '-': Not scanned -- '0': Clean (no security findings detected) - - -subnet.tf (terraform) -===================== -Tests: 3 (SUCCESSES: 0, FAILURES: 3) -Failures: 3 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 3, CRITICAL: 0) - -AVD-AWS-0164 (HIGH): Subnet associates public IP address. -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ -You should limit the provision of public IP addresses for resources. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application. - - -See https://avd.aquasec.com/misconfig/aws-vpc-no-public-ingress-sgr -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - subnet.tf:7 - via subnet.tf:1-13 (aws_subnet.public["a"]) -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - 1 resource "aws_subnet" "public" { - . - 7 [ map_public_ip_on_launch = true - .. - 13 } -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - - -AVD-AWS-0164 (HIGH): Subnet associates public IP address. -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ -You should limit the provision of public IP addresses for resources. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application. - - -See https://avd.aquasec.com/misconfig/aws-vpc-no-public-ingress-sgr -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - subnet.tf:7 - via subnet.tf:1-13 (aws_subnet.public["b"]) -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - 1 resource "aws_subnet" "public" { - . - 7 [ map_public_ip_on_launch = true - .. - 13 } -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - - -AVD-AWS-0164 (HIGH): Subnet associates public IP address. -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ -You should limit the provision of public IP addresses for resources. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application. - - -See https://avd.aquasec.com/misconfig/aws-vpc-no-public-ingress-sgr -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - subnet.tf:7 - via subnet.tf:1-13 (aws_subnet.public["c"]) -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - 1 resource "aws_subnet" "public" { - . - 7 [ map_public_ip_on_launch = true - .. - 13 } -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - - - -vpc.tf (terraform) -================== -Tests: 1 (SUCCESSES: 0, FAILURES: 1) -Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0) - -AVD-AWS-0178 (MEDIUM): VPC does not have VPC Flow Logs enabled. -════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ -VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows. - - -See https://avd.aquasec.com/misconfig/aws-autoscaling-enable-at-rest-encryption -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - vpc.tf:1-9 -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - 1 ┌ resource "aws_vpc" "this" { - 2 │ cidr_block = local.vpc_cidr - 3 │ enable_dns_support = true - 4 │ enable_dns_hostnames = true - 5 │ - 6 │ tags = { - 7 │ Name = local.name_prefix - 8 │ } - 9 └ } -──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── - -