From d274e01c98a3dca7e1bc929d42c0e90a3efdde80 Mon Sep 17 00:00:00 2001 From: Chandan-DK Date: Wed, 24 Jul 2024 17:16:39 +0000 Subject: [PATCH 1/2] add ecs best practices Signed-off-by: Chandan-DK --- .../check-awsvpc-network-mode/README.md | 77 +++++++++ .../check-awsvpc-network-mode.yaml | 28 ++++ .../check-awsvpc-network-mode/test/bad-01.tf | 46 ++++++ .../check-awsvpc-network-mode/test/bad-02.tf | 71 +++++++++ .../test/bad-payload-01.json | 44 ++++++ .../test/bad-payload-02.json | 56 +++++++ .../test/binding.yaml | 3 + .../test/chainsaw-test.yaml | 93 +++++++++++ .../test/good-payload.json | 44 ++++++ .../check-awsvpc-network-mode/test/good.tf | 46 ++++++ .../README.md | 90 +++++++++++ .../test/bad-payload.json | 48 ++++++ .../test/bad.tf | 34 ++++ .../test/binding.yaml | 3 + .../test/chainsaw-test.yaml | 60 +++++++ .../test/good-payload.json | 54 +++++++ .../test/good.tf | 39 +++++ ...lidate-ecs-container-insights-enabled.yaml | 26 ++++ .../README.md | 95 ++++++++++++ .../test/bad-payload.json | 45 ++++++ .../test/bad.tf | 65 ++++++++ .../test/binding.yaml | 3 + .../test/chainsaw-test.yaml | 60 +++++++ .../test/good-payload.json | 44 ++++++ .../test/good.tf | 65 ++++++++ ...te-ecs-task-definition-pid-mode-check.yaml | 25 +++ .../validate-ecs-task-public-ip/README.md | 95 ++++++++++++ .../test/bad-payload.json | 119 ++++++++++++++ .../validate-ecs-task-public-ip/test/bad.tf | 76 +++++++++ .../test/binding.yaml | 3 + .../test/chainsaw-test.yaml | 60 +++++++ .../test/good-payload.json | 119 ++++++++++++++ .../validate-ecs-task-public-ip/test/good.tf | 76 +++++++++ .../validate-ecs-task-public-ip.yaml | 28 ++++ .../validate-efs-volume-encryption/README.md | 93 +++++++++++ .../test/bad-payload.json | 69 +++++++++ .../test/bad-payload1.json | 70 +++++++++ .../test/bad.tf | 84 ++++++++++ .../test/bad1.tf | 85 ++++++++++ .../test/binding.yaml | 3 + .../test/chainsaw-test.yaml | 146 ++++++++++++++++++ .../test/good-payload.json | 70 +++++++++ .../test/good-payload1.json | 57 +++++++ .../test/good-payload2.json | 44 ++++++ .../test/good.tf | 85 ++++++++++ .../test/good1.tf | 74 +++++++++ .../test/good2.tf | 47 ++++++ .../validate-efs-volume-encryption.yaml | 29 ++++ 48 files changed, 2796 insertions(+) create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/README.md create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/check-awsvpc-network-mode.yaml create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/bad-01.tf create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/bad-02.tf create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/bad-payload-01.json create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/bad-payload-02.json create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/binding.yaml create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/chainsaw-test.yaml create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/good-payload.json create mode 100644 terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/good.tf create mode 100644 terraform/config/ecs-best-practices/validate-ecs-container-insights-enabled/README.md create mode 100644 terraform/config/ecs-best-practices/validate-ecs-container-insights-enabled/test/bad-payload.json create mode 100644 terraform/config/ecs-best-practices/validate-ecs-container-insights-enabled/test/bad.tf create mode 100644 terraform/config/ecs-best-practices/validate-ecs-container-insights-enabled/test/binding.yaml create mode 100644 terraform/config/ecs-best-practices/validate-ecs-container-insights-enabled/test/chainsaw-test.yaml create mode 100644 terraform/config/ecs-best-practices/validate-ecs-container-insights-enabled/test/good-payload.json create mode 100644 terraform/config/ecs-best-practices/validate-ecs-container-insights-enabled/test/good.tf create mode 100644 terraform/config/ecs-best-practices/validate-ecs-container-insights-enabled/validate-ecs-container-insights-enabled.yaml create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/README.md create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/bad-payload.json create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/bad.tf create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/binding.yaml create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/chainsaw-test.yaml create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/good-payload.json create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/good.tf create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/validate-ecs-task-definition-pid-mode-check.yaml create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-public-ip/README.md create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/bad-payload.json create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/bad.tf create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/binding.yaml create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/chainsaw-test.yaml create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/good-payload.json create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/good.tf create mode 100644 terraform/config/ecs-best-practices/validate-ecs-task-public-ip/validate-ecs-task-public-ip.yaml create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/README.md create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad-payload.json create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad-payload1.json create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad.tf create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad1.tf create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/binding.yaml create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/chainsaw-test.yaml create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/good-payload.json create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/good-payload1.json create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/good-payload2.json create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/good.tf create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/good1.tf create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/good2.tf create mode 100644 terraform/config/ecs-best-practices/validate-efs-volume-encryption/validate-efs-volume-encryption.yaml diff --git a/terraform/config/ecs-best-practices/check-awsvpc-network-mode/README.md b/terraform/config/ecs-best-practices/check-awsvpc-network-mode/README.md new file mode 100644 index 00000000..bddd7f34 --- /dev/null +++ b/terraform/config/ecs-best-practices/check-awsvpc-network-mode/README.md @@ -0,0 +1,77 @@ +# Check `awsvpc` network mode + +When you're running containers on AWS, managing the networking becomes crucial, especially when leveraging the benefits of hosting multiple containers on a single host. There are various network modes to choose from: + +1. **Host mode:** This is the most basic network mode in Amazon ECS. It essentially shares the host's networking stack with the containers. + +2. **Bridge mode:** This mode employs a virtual network bridge to establish a layer between the host and the container's networking. + +3. **AWSVPC mode:** Here, Amazon ECS generates and oversees an Elastic Network Interface (ENI) for each task, providing each task with a distinct private IP address within the VPC. + +By default, the network mode for ECS tasks is set to `bridge`. However, we will opt for the `awsvpc` network mode here. This choice is strategic, as it facilitates controlled traffic flow between tasks and enhances security. `awsvpc` offers task-level network isolation for tasks running on Amazon EC2. Importantly, it's the exclusive network mode allowing the assignment of security groups to tasks. + +To formalize our approach, it's prudent to establish a policy that ensures the usage of 'awsvpc' network mode. This policy aligns with our security strategy by adding an extra layer of protection through task-level isolation and the ability to apply security groups at the task level. Therefore, adopting and enforcing this policy safeguards our containerized infrastructure while optimizing networking capabilities on AWS. + +### Policy Validation Testing Instructions + +To evaluate and test the policy ensuring the presence of the `awsvpc` network mode in the Terraform config file, follow the steps outlined below: + +For testing this policy you will need to: +- Make sure you have `nctl` installed on the machine + +1. **Test the Policy with nctl:** + ``` + nctl scan terraform --resources tf-config.tf --policy policy.yaml + ``` + + a. **Test Policy Against Valid Terraform Config File:** + ``` + nctl scan terraform --resources test/good.tf --policies check-awsvpc-network-mode.yaml + ``` + + This produces the output: + ``` + Version: 4.0.1 + Fetching policies... + Loading policies... + • found 1 policies + Running analysis... + • no errors + Results... + +---------------------------+---------------------------+--------------+---------+--------+ + | POLICY | RULE | RESOURCE | MESSAGE | RESULT | + +---------------------------+---------------------------+--------------+---------+--------+ + | check-awsvpc-network-mode | check-awsvpc-network-mode | test/good.tf | | pass | + +---------------------------+---------------------------+--------------+---------+--------+ + + Done + ``` + + b. **Test Against Invalid Terraform Config File:** + ``` + nctl scan terraform --resources test/bad-01.tf --policies check-awsvpc-network-mode.yaml + ``` + + This produces the output: + ``` + Version: 4.0.1 + Fetching policies... + Loading policies... + • found 1 policies + Running analysis... + • no errors + Results... + +---------------------------+---------------------------+----------------+--------------------------------------------------------------------------------+--------+ + | POLICY | RULE | RESOURCE | MESSAGE | RESULT | + +---------------------------+---------------------------+----------------+--------------------------------------------------------------------------------+--------+ + | check-awsvpc-network-mode | check-awsvpc-network-mode | test/bad-01.tf | ECS services and tasks are required to use awsvpc network mode.: | fail | + | | | | all[0].check.~.(resource.aws_ecs_task_definition.values(@)[])[0].network_mode: | | + | | | | Invalid value: "bridge": Expected value: "awsvpc" | | + +---------------------------+---------------------------+----------------+--------------------------------------------------------------------------------+--------+ + + Done + ``` + +--- + +These instructions are designed to systematically assess the compliance of Terraform config files with the defined policy. Following these steps ensures a thorough examination of the `awsvpc` network mode presence in the terraform config file, allowing for effective validation and adherence to the specified policy. \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/check-awsvpc-network-mode/check-awsvpc-network-mode.yaml b/terraform/config/ecs-best-practices/check-awsvpc-network-mode/check-awsvpc-network-mode.yaml new file mode 100644 index 00000000..3efd3d25 --- /dev/null +++ b/terraform/config/ecs-best-practices/check-awsvpc-network-mode/check-awsvpc-network-mode.yaml @@ -0,0 +1,28 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: check-awsvpc-network-mode + labels: + ecs.aws.network.kyverno.io: awsvpc + annotations: + policies.kyverno.io/title: Check awsvpc network mode + policies.kyverno.io/category: ECS Best Practices + policies.kyverno.io/severity: medium + policies.kyverno.io/description: >- + The awsvpc network mode restricts the flow of traffic between different + tasks or between your tasks and other services that run within your Amazon VPC. + The awsvpc network mode provides task-level network isolation for tasks + that run on Amazon EC2. +spec: + rules: + - name: check-awsvpc-network-mode + match: + all: + - ($analyzer.resource.type): terraform-config + - (resource.aws_ecs_task_definition != null): true + assert: + all: + - message: ECS services and tasks are required to use awsvpc network mode. + check: + ~.(resource.aws_ecs_task_definition.values(@)[]): + network_mode: awsvpc diff --git a/terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/bad-01.tf b/terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/bad-01.tf new file mode 100644 index 00000000..78cdbb45 --- /dev/null +++ b/terraform/config/ecs-best-practices/check-awsvpc-network-mode/test/bad-01.tf @@ -0,0 +1,46 @@ +resource "aws_ecs_task_definition" "task" { + family = "service" + network_mode = "bridge" + requires_compatibilities = ["EC2"] + cpu = 512 + memory = 2048 + container_definitions = <- + This Policy ensures that ECS clusters have container + insights enabled. +spec: + rules: + - name: validate-ecs-container-insights-enabled + match: + all: + - ($analyzer.resource.type): terraform-config + - (resource.aws_ecs_cluster != null): true + assert: + all: + - message: ECS container insights are not enabled + check: + ~.(resource.aws_ecs_cluster.values(@)[]): + ~.(setting || `[{}]`): + value: enabled + diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/README.md b/terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/README.md new file mode 100644 index 00000000..2c18f8a0 --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/README.md @@ -0,0 +1,95 @@ +# Validate ECS Task Definition PID Mode Policy + +This policy ensures that Amazon ECS task definitions do not share the host's process namespace, aligning with security standards (NIST 800-53 controls CA-9(1) and CM-2). If the host PID mode is used, there's a heightened risk of undesired process namespace exposure. + +## Policy Details: + +- **Policy Name:** validate-ecs-task-definition-pid-mode-check +- **Check Description:** This policy ensures that ECS task definitions do not share the host's process namespace +- **Policy Category:** AWS ECS Best Practices + +## How It Works: + +### Validation Criteria: + +**Key** : pid_mode +**Valid Values** : host | task | null +**Type** : string +**Required** : No + +- **Condition:** `pid_mode` is set to `task` + - **Result:** PASS + - **Reason:** If task is specified, all containers within the specified task share the same process namespace. + + +- **Condition:** `pid_mode` is set to `null` + - **Result:** PASS + - **Reason:** If no value is specified, the default is a private namespace for each container. + +- **Condition:** `pid_mode` is set to `host` + - **Result:** FAIL + - **Reason:** If host is specified, all containers within the tasks that specified the host PID mode on the same container instance share the same process namespace with the host Amazon EC2 instance. + +### Policy Validation Testing Instructions + +To evaluate and test the policy ensuring ECS task definitions meet security standards: + +For testing this policy you will need to: +- Make sure you have `nctl` installed on the machine + +1. **Test the Policy with nctl:** + ``` + nctl scan terraform --resources tf-config.tf --policy policy.yaml + ``` + + a. **Test Policy Against Valid Terraform Config File:** + ``` + nctl scan terraform --resources test/good.tf --policies validate-ecs-task-definition-pid-mode-check.yaml + ``` + + This produces the output: + ``` + Version: 4.0.1 + Fetching policies... + Loading policies... + • found 1 policies + Running analysis... + • no errors + Results... + +---------------------------------------------+---------------------------------------------+--------------+---------+--------+ + | POLICY | RULE | RESOURCE | MESSAGE | RESULT | + +---------------------------------------------+---------------------------------------------+--------------+---------+--------+ + | validate-ecs-task-definition-pid-mode-check | validate-ecs-task-definition-pid-mode-check | test/good.tf | | pass | + +---------------------------------------------+---------------------------------------------+--------------+---------+--------+ + + Done + ``` + + b. **Test Against Invalid Terraform Config File:** + ``` + nctl scan terraform --resources test/bad.tf --policies validate-ecs-task-definition-pid-mode-check.yaml + ``` + + This produces the output: + ``` + Version: 4.0.1 + Fetching policies... + Loading policies... + • found 1 policies + Running analysis... + • no errors + Results... + +---------------------------------------------+---------------------------------------------+-------------+----------------------------------------------------------------------------+--------+ + | POLICY | RULE | RESOURCE | MESSAGE | RESULT | + +---------------------------------------------+---------------------------------------------+-------------+----------------------------------------------------------------------------+--------+ + | validate-ecs-task-definition-pid-mode-check | validate-ecs-task-definition-pid-mode-check | test/bad.tf | ECS task definitions shares the host's process namespace: | fail | + | | | | all[0].check.~.(resource.aws_ecs_task_definition.values(@)[])[0].(pid_mode | | + | | | | || 'task'): Invalid value: "host": Expected value: "task" | | + +---------------------------------------------+---------------------------------------------+-------------+----------------------------------------------------------------------------+--------+ + + Done + ``` + +--- + +This way you can ensure that your ECS task definitions adhere to security standards regarding the sharing of the host's process namespace. diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/bad-payload.json b/terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/bad-payload.json new file mode 100644 index 00000000..7f38a31e --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/bad-payload.json @@ -0,0 +1,45 @@ +{ + "provider": { + "aws": [ + { + "region": "us-west-1" + } + ], + "docker": [ + {} + ] + }, + "resource": { + "aws_ecs_task_definition": { + "bad_task": [ + { + "container_definitions": " [\n {\n \"name\" : \"foo-task\",\n \"image\" : \"nginx:1.23.1\",\n \"cpu\" : 512,\n \"memory\" : 2048,\n \"essential\" : true,\n \"portMappings\" : [\n {\n \"containerPort\" : 80,\n \"hostPort\" : 80\n }\n ]\n }\n ]\n", + "family": "service", + "pid_mode": "host" + } + ], + "good_task": [ + { + "container_definitions": " [\n {\n \"name\" : \"bar-task\",\n \"image\" : \"httpd:2.4\",\n \"cpu\" : 256,\n \"memory\" : 1024,\n \"essential\" : true,\n \"portMappings\" : [\n {\n \"containerPort\" : 8080,\n \"hostPort\" : 8080\n }\n ]\n }\n ]\n", + "family": "service-2" + } + ] + } + }, + "terraform": [ + { + "required_providers": [ + { + "aws": { + "source": "hashicorp/aws", + "version": "~\u003e 4.0" + }, + "docker": { + "source": "kreuzwerker/docker", + "version": "~\u003e2.20.0" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/bad.tf b/terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/bad.tf new file mode 100644 index 00000000..40ef86c5 --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-definition-pid-mode-check/test/bad.tf @@ -0,0 +1,65 @@ +resource "aws_ecs_task_definition" "bad_task" { + family = "service" + pid_mode = "host" + container_definitions = <- + This policy ensures that ECS task definitions do not share the host's process namespace +spec: + rules: + - name: validate-ecs-task-definition-pid-mode-check + match: + all: + - ($analyzer.resource.type): terraform-config + - (resource.aws_ecs_task_definition != null): true + assert: + all: + - message: ECS task definitions shares the host's process namespace + check: + ~.(resource.aws_ecs_task_definition.values(@)[]): + (pid_mode || 'task'): task diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/README.md b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/README.md new file mode 100644 index 00000000..251d0195 --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/README.md @@ -0,0 +1,95 @@ +# Validate ECS Task Public IP + +A public IP address is an IP address that is reachable from the internet. If you launch your Amazon ECS instances with a public IP address, then your Amazon ECS instances are reachable from the internet. Amazon ECS services should not be publicly accessible, as this may allow unintended access to your container application servers. + +## Policy Details: + +- **Policy Name:** validate-ecs-task-public-ip +- **Check Description:** ECS tasks with public IP address enabled, are easily reachable from the internet. This policy validates whether public IP address is enabled on the ECS task. +- **Policy Category:** AWS ECS Best Practices + +## How It Works: + +### Validation Criteria: + +**Key** : assign_public_ip +**Valid Values** : true | false | not set +**Type** : string +**Required** : No + +- **Condition:** `assign_public_ip` is set to `false` + - **Result:** PASS + - **Reason:** + + +- **Condition:** `assign_public_ip` is not present + - **Result:** PASS + - **Reason:** + +- - **Condition:** `network_configuration` is not present + - **Result:** PASS + - **Reason:** + +- **Condition:** `assign_public_ip` is set to `true` + - **Result:** FAIL + - **Reason:** + +### Policy Validation Testing Instructions + +For testing this policy you will need to: +- Make sure you have `nctl` installed on the machine + +1. **Test the Policy with nctl:** + ``` + nctl scan terraform --resources tf-config.tf --policy policy.yaml + ``` + + a. **Test Policy Against Valid Terraform Config File:** + ``` + nctl scan terraform --resources test/good.tf --policies validate-ecs-task-public-ip.yaml + ``` + + This produces the output: + ``` + Version: 4.0.1 + Fetching policies... + Loading policies... + • found 1 policies + Running analysis... + • no errors + Results... + +-----------------------------+-----------------------------+--------------+---------+--------+ + | POLICY | RULE | RESOURCE | MESSAGE | RESULT | + +-----------------------------+-----------------------------+--------------+---------+--------+ + | validate-ecs-task-public-ip | validate-ecs-task-public-ip | test/good.tf | | pass | + +-----------------------------+-----------------------------+--------------+---------+--------+ + + Done + ``` + + b. **Test Against Invalid Terraform Config File:** + ``` + nctl scan terraform --resources test/bad.tf --policies validate-ecs-task-public-ip.yaml + ``` + + This produces the output: + ``` + Version: 4.0.1 + Fetching policies... + Loading policies... + • found 1 policies + Running analysis... + • no errors + Results... + +-----------------------------+-----------------------------+-------------+------------------------------------------------------------------------------------------------------+--------+ + | POLICY | RULE | RESOURCE | MESSAGE | RESULT | + +-----------------------------+-----------------------------+-------------+------------------------------------------------------------------------------------------------------+--------+ + | validate-ecs-task-public-ip | validate-ecs-task-public-ip | test/bad.tf | Public IP address should not be enabled: | fail | + | | | | any[0].check.~.(resource.aws_ecs_service.values(@)[])[0].~.(network_configuration[?assign_public_ip] | | + | | | | || `[]`)[0].assign_public_ip: Invalid value: true: Expected value: false | | + +-----------------------------+-----------------------------+-------------+------------------------------------------------------------------------------------------------------+--------+ + + Done + ``` + +--- diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/bad-payload.json b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/bad-payload.json new file mode 100644 index 00000000..78d46b70 --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/bad-payload.json @@ -0,0 +1,119 @@ +{ + "provider": { + "aws": [ + { + "region": "us-west-1" + } + ], + "docker": [ + {} + ] + }, + "resource": { + "aws_ecs_cluster": { + "cluster": [ + { + "name": "cluster", + "setting": [ + { + "name": "containerInsights", + "value": "enabled" + } + ] + } + ] + }, + "aws_ecs_service": { + "bad_service": [ + { + "cluster": "${aws_ecs_cluster.cluster.id}", + "desired_count": 1, + "launch_type": "EC2", + "lifecycle": [ + { + "ignore_changes": [ + "${task_definition}" + ] + } + ], + "name": "bad-service", + "network_configuration": [ + { + "assign_public_ip": true, + "subnets": [ + "${aws_subnet.subnet.id}" + ] + } + ] + } + ], + "good_service": [ + { + "cluster": "${aws_ecs_cluster.cluster.id}", + "desired_count": 1, + "launch_type": "EC2", + "lifecycle": [ + { + "ignore_changes": [ + "${task_definition}" + ] + } + ], + "name": "good-service", + "network_configuration": [ + { + "assign_public_ip": false, + "subnets": [ + "${aws_subnet.subnet.id}" + ] + } + ] + } + ] + }, + "aws_subnet": { + "subnet": [ + { + "cidr_block": "${cidrsubnet(aws_vpc.main.cidr_block, 8, 1)}", + "map_public_ip_on_launch": true, + "vpc_id": "${aws_vpc.main.id}" + } + ] + }, + "aws_vpc": { + "main": [ + { + "cidr_block": "${var.vpc_cidr}", + "tags": { + "name": "main" + } + } + ] + } + }, + "terraform": [ + { + "required_providers": [ + { + "aws": { + "source": "hashicorp/aws", + "version": "~\u003e 4.0" + }, + "docker": { + "source": "kreuzwerker/docker", + "version": "~\u003e2.20.0" + } + } + ] + } + ], + "variable": { + "vpc_cidr": [ + { + "default": "10.0.0.0/16", + "description": "CIDR block for main", + "type": "${string}" + } + ] + } +} \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/bad.tf b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/bad.tf new file mode 100644 index 00000000..ab43407a --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/bad.tf @@ -0,0 +1,76 @@ +resource "aws_ecs_service" "bad_service" { + name = "bad-service" + cluster = aws_ecs_cluster.cluster.id + desired_count = 1 + launch_type = "EC2" + network_configuration { + assign_public_ip = true + subnets = [aws_subnet.subnet.id] + } + lifecycle { + ignore_changes = [task_definition] + } +} + +resource "aws_ecs_service" "good_service" { + name = "good-service" + cluster = aws_ecs_cluster.cluster.id + desired_count = 1 + launch_type = "EC2" + network_configuration { + assign_public_ip = false + subnets = [aws_subnet.subnet.id] + } + lifecycle { + ignore_changes = [task_definition] + } +} + +resource "aws_ecs_cluster" "cluster" { + name = "cluster" + setting { + name = "containerInsights" + value = "enabled" + } +} + +resource "aws_subnet" "subnet" { + vpc_id = aws_vpc.main.id + cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, 1) ## takes 10.0.0.0/16 --> 10.0.1.0/24 + map_public_ip_on_launch = true +} + +resource "aws_vpc" "main" { + cidr_block = var.vpc_cidr + tags = { + name = "main" + } +} + +variable "vpc_cidr" { + description = "CIDR block for main" + type = string + default = "10.0.0.0/16" +} + +# Setting up the configuration for using Docker and AWS providers + +terraform { + required_providers { + docker = { + source = "kreuzwerker/docker" + version = "~>2.20.0" + } + aws = { + source = "hashicorp/aws" + version = "~> 4.0" + } + } +} + +# Configuring docker and AWS as providers +provider "docker" {} + +provider "aws" { + region = "us-west-1" +} \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/binding.yaml b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/binding.yaml new file mode 100644 index 00000000..5d03d04f --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/binding.yaml @@ -0,0 +1,3 @@ +analyzer: + resource: + type: terraform-config \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/chainsaw-test.yaml b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/chainsaw-test.yaml new file mode 100644 index 00000000..1086b406 --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/chainsaw-test.yaml @@ -0,0 +1,60 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: good-test +spec: + steps: + - name: kyverno-json + try: + - script: + content: | + set -e + kyverno-json scan --policy ../validate-ecs-task-public-ip.yaml --payload good-payload.json --output json --bindings ./binding.yaml + check: + ($error): ~ + (json_parse($stdout)): + - results: + - policy: + apiVersion: json.kyverno.io/v1alpha1 + kind: ValidatingPolicy + metadata: + name: validate-ecs-task-public-ip + rules: + - rule: + name: validate-ecs-task-public-ip + error: ~ + violations: ~ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: Test +metadata: + name: bad-test +spec: + steps: + - name: kyverno-json + try: + - script: + content: | + set -e + kyverno-json scan --policy ../validate-ecs-task-public-ip.yaml --payload bad-payload.json --output json --bindings ./binding.yaml + check: + ($error): ~ + (json_parse($stdout)): + - results: + - policy: + apiVersion: json.kyverno.io/v1alpha1 + kind: ValidatingPolicy + metadata: + name: validate-ecs-task-public-ip + rules: + - rule: + name: validate-ecs-task-public-ip + error: ~ + violations: + - message: Public IP address should not be enabled + errors: + - type: FieldValueInvalid + value: true + detail: 'Expected value: false' diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/good-payload.json b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/good-payload.json new file mode 100644 index 00000000..843f13fd --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/good-payload.json @@ -0,0 +1,119 @@ +{ + "provider": { + "aws": [ + { + "region": "us-west-1" + } + ], + "docker": [ + {} + ] + }, + "resource": { + "aws_ecs_cluster": { + "cluster": [ + { + "name": "cluster", + "setting": [ + { + "name": "containerInsights", + "value": "enabled" + } + ] + } + ] + }, + "aws_ecs_service": { + "service": [ + { + "cluster": "${aws_ecs_cluster.cluster.id}", + "desired_count": 1, + "launch_type": "EC2", + "lifecycle": [ + { + "ignore_changes": [ + "${task_definition}" + ] + } + ], + "name": "foo-service", + "network_configuration": [ + { + "assign_public_ip": false, + "subnets": [ + "${aws_subnet.subnet.id}" + ] + } + ] + } + ], + "service_2": [ + { + "cluster": "${aws_ecs_cluster.cluster.id}", + "desired_count": 1, + "launch_type": "EC2", + "lifecycle": [ + { + "ignore_changes": [ + "${task_definition}" + ] + } + ], + "name": "bar-service", + "network_configuration": [ + { + "assign_public_ip": false, + "subnets": [ + "${aws_subnet.subnet.id}" + ] + } + ] + } + ] + }, + "aws_subnet": { + "subnet": [ + { + "cidr_block": "${cidrsubnet(aws_vpc.main.cidr_block, 8, 1)}", + "map_public_ip_on_launch": true, + "vpc_id": "${aws_vpc.main.id}" + } + ] + }, + "aws_vpc": { + "main": [ + { + "cidr_block": "${var.vpc_cidr}", + "tags": { + "name": "main" + } + } + ] + } + }, + "terraform": [ + { + "required_providers": [ + { + "aws": { + "source": "hashicorp/aws", + "version": "~\u003e 4.0" + }, + "docker": { + "source": "kreuzwerker/docker", + "version": "~\u003e2.20.0" + } + } + ] + } + ], + "variable": { + "vpc_cidr": [ + { + "default": "10.0.0.0/16", + "description": "CIDR block for main", + "type": "${string}" + } + ] + } +} \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/good.tf b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/good.tf new file mode 100644 index 00000000..4f870166 --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/test/good.tf @@ -0,0 +1,76 @@ +resource "aws_ecs_service" "service" { + name = "foo-service" + cluster = aws_ecs_cluster.cluster.id + desired_count = 1 + launch_type = "EC2" + network_configuration { + assign_public_ip = false + subnets = [aws_subnet.subnet.id] + } + lifecycle { + ignore_changes = [task_definition] + } +} + +resource "aws_ecs_service" "service_2" { + name = "bar-service" + cluster = aws_ecs_cluster.cluster.id + desired_count = 1 + launch_type = "EC2" + network_configuration { + assign_public_ip = false + subnets = [aws_subnet.subnet.id] + } + lifecycle { + ignore_changes = [task_definition] + } +} + +resource "aws_ecs_cluster" "cluster" { + name = "cluster" + setting { + name = "containerInsights" + value = "enabled" + } +} + +resource "aws_subnet" "subnet" { + vpc_id = aws_vpc.main.id + cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, 1) ## takes 10.0.0.0/16 --> 10.0.1.0/24 + map_public_ip_on_launch = true +} + +resource "aws_vpc" "main" { + cidr_block = var.vpc_cidr + tags = { + name = "main" + } +} + +variable "vpc_cidr" { + description = "CIDR block for main" + type = string + default = "10.0.0.0/16" +} + +# Setting up the configuration for using Docker and AWS providers + +terraform { + required_providers { + docker = { + source = "kreuzwerker/docker" + version = "~>2.20.0" + } + aws = { + source = "hashicorp/aws" + version = "~> 4.0" + } + } +} + +# Configuring docker and AWS as providers +provider "docker" {} + +provider "aws" { + region = "us-west-1" +} \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/validate-ecs-task-public-ip.yaml b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/validate-ecs-task-public-ip.yaml new file mode 100644 index 00000000..1b763e1c --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-ecs-task-public-ip/validate-ecs-task-public-ip.yaml @@ -0,0 +1,28 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: validate-ecs-task-public-ip + labels: + ecs.aws.tags.kyverno.io: ecs-service + annotations: + policies.kyverno.io/title: Validate ECS Task Public IP + policies.kyverno.io/category: ECS Best Practices + policies.kyverno.io/severity: medium + policies.kyverno.io/description: >- + ECS tasks with public IP address enabled, are easily reachable from the internet. + This policy validates whether public IP address is enabled on the ECS task +spec: + rules: + - name: validate-ecs-task-public-ip + match: + all: + - ($analyzer.resource.type): terraform-config + - (resource.aws_ecs_service != null): true + assert: + any: + - message: Public IP address should not be enabled + check: + ~.(resource.aws_ecs_service.values(@)[]): + ~.(network_configuration[?assign_public_ip] || `[]`): + assign_public_ip: false + diff --git a/terraform/config/ecs-best-practices/validate-efs-volume-encryption/README.md b/terraform/config/ecs-best-practices/validate-efs-volume-encryption/README.md new file mode 100644 index 00000000..57a33ab3 --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-efs-volume-encryption/README.md @@ -0,0 +1,93 @@ +# Validate EFS Volume Encryption + +Amazon EFS file systems can be used with Amazon ECS to export file system data across your fleet of container instances. To ensure encryption is enabled in transit, this policy validates whether transit_encryption is set to ENABLED in the task definition. + +## Policy Details: + +- **Policy Name:** validate-efs-volume-encryption +- **Check Description:** Ensure Transit Encryption is enabled for EFS volumes in ECS Task definitions +- **Policy Category:** AWS ECS Best Practices + +## How It Works: + +### Validation Criteria: + +**Key** : transit_encryption +**Valid Values** : ENABLED | DISABLED +**Type** : string +**Required** : No + +- **Condition:** `transit_encryption` is set to `ENABLED` + - **Result:** PASS + - **Reason:** Transit Encryption is enabled for EFS volumes in ECS Task definitions + + +- **Condition:** `transit_encryption` is set to `DISABLED` + - **Result:** FAIL + - **Reason:** Transit Encryption is disabled for EFS volumes in ECS Task definitions + +- **Condition:** `transit_encryption` is omitted + - **Result:** FAIL + - **Reason:** If `transit_encryption` is omitted, the default value of DISABLED is used. + +### Policy Validation Testing Instructions + +For testing this policy you will need to: +- Make sure you have `nctl` installed on the machine + +1. **Test the Policy with nctl:** + ``` + nctl scan terraform --resources tf-config.tf --policy policy.yaml + ``` + + a. **Test Policy Against Valid Terraform Config File:** + ``` + nctl scan terraform --resources test/good1.tf --policies validate-efs-volume-encryption.yaml + ``` + + This produces the output: + ``` + Version: 4.0.1 + Fetching policies... + Loading policies... + • found 1 policies + Running analysis... + • no errors + Results... + +--------------------------------+--------------------------------+---------------+---------+--------+ + | POLICY | RULE | RESOURCE | MESSAGE | RESULT | + +--------------------------------+--------------------------------+---------------+---------+--------+ + | validate-efs-volume-encryption | validate-efs-volume-encryption | test/good1.tf | | pass | + +--------------------------------+--------------------------------+---------------+---------+--------+ + + Done + ``` + + b. **Test Against Invalid Terraform Config File:** + ``` + nctl scan terraform --resources test/bad.tf --policies validate-efs-volume-encryption.yaml + ``` + + This produces the output: + ``` + Version: 4.0.1 + Fetching policies... + Loading policies... + • found 1 policies + Running analysis... + • no errors + Results... + +--------------------------------+--------------------------------+-------------+----------------------------------------------------------------------------+--------+ + | POLICY | RULE | RESOURCE | MESSAGE | RESULT | + +--------------------------------+--------------------------------+-------------+----------------------------------------------------------------------------+--------+ + | validate-efs-volume-encryption | validate-efs-volume-encryption | test/bad.tf | Transit Encryption is not `ENABLED` for | fail | + | | | | EFS volumes in ECS Task definitions: | | + | | | | all[0].check.~.(resource.aws_ecs_task_definition.values(@)[])[1].~.(volume | | + | | | | || `[]`)[0].~.(efs_volume_configuration || `[]`)[0].(transit_encryption == | | + | | | | 'ENABLED'): Invalid value: false: Expected value: true | | + +--------------------------------+--------------------------------+-------------+----------------------------------------------------------------------------+--------+ + + Done + ``` + +--- \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad-payload.json b/terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad-payload.json new file mode 100644 index 00000000..3d2aeda5 --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad-payload.json @@ -0,0 +1,69 @@ +{ + "provider": { + "aws": [ + { + "region": "us-west-1" + } + ], + "docker": [ + {} + ] + }, + "resource": { + "aws_ecs_task_definition": { + "bad_service": [ + { + "container_definitions": " [\n {\n \"name\" : \"foo-task\",\n \"image\" : \"nginx:1.23.1\",\n \"cpu\" : 512,\n \"memory\" : 2048,\n \"essential\" : true,\n \"portMappings\" : [\n {\n \"containerPort\" : 80,\n \"hostPort\" : 80\n }\n ]\n }\n ]\n", + "family": "bad-service", + "volume": [ + { + "efs_volume_configuration": [ + { + "file_system_id": "fs-0123456789abcdef0", + "root_directory": "/opt/data", + "transit_encryption_port": 2999 + } + ], + "name": "service-storage" + } + ] + } + ], + "good_service": [ + { + "container_definitions": " [\n {\n \"name\" : \"foo-task\",\n \"image\" : \"nginx:1.23.1\",\n \"cpu\" : 512,\n \"memory\" : 2048,\n \"essential\" : true,\n \"portMappings\" : [\n {\n \"containerPort\" : 80,\n \"hostPort\" : 80\n }\n ]\n }\n ]\n", + "family": "good-service", + "volume": [ + { + "efs_volume_configuration": [ + { + "file_system_id": "fs-0123456789abcdef0", + "root_directory": "/opt/data", + "transit_encryption": "ENABLED", + "transit_encryption_port": 2999 + } + ], + "name": "service-storage" + } + ] + } + ] + } + }, + "terraform": [ + { + "required_providers": [ + { + "aws": { + "source": "hashicorp/aws", + "version": "~\u003e 4.0" + }, + "docker": { + "source": "kreuzwerker/docker", + "version": "~\u003e2.20.0" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad-payload1.json b/terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad-payload1.json new file mode 100644 index 00000000..fb6048c3 --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad-payload1.json @@ -0,0 +1,70 @@ +{ + "provider": { + "aws": [ + { + "region": "us-west-1" + } + ], + "docker": [ + {} + ] + }, + "resource": { + "aws_ecs_task_definition": { + "bad_service": [ + { + "container_definitions": " [\n {\n \"name\" : \"foo-task\",\n \"image\" : \"nginx:1.23.1\",\n \"cpu\" : 512,\n \"memory\" : 2048,\n \"essential\" : true,\n \"portMappings\" : [\n {\n \"containerPort\" : 80,\n \"hostPort\" : 80\n }\n ]\n }\n ]\n", + "family": "bad-service", + "volume": [ + { + "efs_volume_configuration": [ + { + "file_system_id": "fs-0123456789abcdef0", + "root_directory": "/opt/data", + "transit_encryption": "DISABLED", + "transit_encryption_port": 2999 + } + ], + "name": "service-storage" + } + ] + } + ], + "good_service": [ + { + "container_definitions": " [\n {\n \"name\" : \"bar-task\",\n \"image\" : \"nginx:1.23.1\",\n \"cpu\" : 512,\n \"memory\" : 2048,\n \"essential\" : true,\n \"portMappings\" : [\n {\n \"containerPort\" : 80,\n \"hostPort\" : 80\n }\n ]\n }\n ]\n", + "family": "good-service", + "volume": [ + { + "efs_volume_configuration": [ + { + "file_system_id": "fs-0123456789abcdef0", + "root_directory": "/opt/data", + "transit_encryption": "ENABLED", + "transit_encryption_port": 2999 + } + ], + "name": "service-storage" + } + ] + } + ] + } + }, + "terraform": [ + { + "required_providers": [ + { + "aws": { + "source": "hashicorp/aws", + "version": "~\u003e 4.0" + }, + "docker": { + "source": "kreuzwerker/docker", + "version": "~\u003e2.20.0" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad.tf b/terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad.tf new file mode 100644 index 00000000..098c4b6c --- /dev/null +++ b/terraform/config/ecs-best-practices/validate-efs-volume-encryption/test/bad.tf @@ -0,0 +1,84 @@ +resource "aws_ecs_task_definition" "bad_service" { + family = "bad-service" + container_definitions = <- + This policy validates whether transit_encryption is set to ENABLED in the task definition. +spec: + rules: + - name: validate-efs-volume-encryption + match: + all: + - ($analyzer.resource.type): terraform-config + - (resource.aws_ecs_task_definition != null): true + assert: + all: + - message: Transit Encryption is not `ENABLED` for EFS volumes in ECS Task definitions + check: + ~.(resource.aws_ecs_task_definition.values(@)[]): + ~.(volume || `[]`): + ~.(efs_volume_configuration || `[]`): + (transit_encryption == 'ENABLED'): true + + From 6b96e3f5c6eb1bb4e126e6b2664d7d364b30367e Mon Sep 17 00:00:00 2001 From: Chandan-DK Date: Wed, 24 Jul 2024 17:19:04 +0000 Subject: [PATCH 2/2] remove the old ecs folder as it is not needed anymore --- .../check-aws-vpc-network-mode.yaml | 32 ------------------- ...lidate-ecs-container-insights-enabled.yaml | 29 ----------------- 2 files changed, 61 deletions(-) delete mode 100644 tf-config-ecs-best-practices/check-aws-vpc-network-mode.yaml delete mode 100644 tf-config-ecs-best-practices/validate-ecs-container-insights-enabled.yaml diff --git a/tf-config-ecs-best-practices/check-aws-vpc-network-mode.yaml b/tf-config-ecs-best-practices/check-aws-vpc-network-mode.yaml deleted file mode 100644 index 70a77637..00000000 --- a/tf-config-ecs-best-practices/check-aws-vpc-network-mode.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: json.kyverno.io/v1alpha1 -kind: ValidatingPolicy -metadata: - name: check-awsvpc-network-mode - labels: - ecs.aws.network.kyverno.io: awsvpc - annotations: - policies.kyverno.io/title: Check awsvpc network mode - policies.kyverno.io/category: ECS Best Practices - policies.kyverno.io/severity: medium - policies.kyverno.io/description: >- - The awsvpc network mode restricts the flow of traffic between different - tasks or between your tasks and other services that run within your Amazon VPC. - The awsvpc network mode provides task-level network isolation for tasks - that run on Amazon EC2. -spec: - rules: - - name: check-awsvpc-network-mode - match: - all: - - ($analyzer): - resource: - type: terraform-config - - (resource.aws_ecs_task_definition && length(resource.aws_ecs_task_definition) > `0`): true - assert: - all: - - message: ECS services and tasks are required to use awsvpc network mode. - check: - resource: - ~.(aws_ecs_task_definition): - ~.(@): - network_mode: awsvpc \ No newline at end of file diff --git a/tf-config-ecs-best-practices/validate-ecs-container-insights-enabled.yaml b/tf-config-ecs-best-practices/validate-ecs-container-insights-enabled.yaml deleted file mode 100644 index 4749754d..00000000 --- a/tf-config-ecs-best-practices/validate-ecs-container-insights-enabled.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: json.kyverno.io/v1alpha1 -kind: ValidatingPolicy -metadata: - name: validate-ecs-container-insights-enabled - annotations: - policies.kyverno.io/title: Validate ECS container insights are enabled - policies.kyverno.io/category: ECS Best Practices - policies.kyverno.io/severity: medium - policies.kyverno.io/description: >- - This Policy ensures that ECS clusters have container - insights enabled. -spec: - rules: - - name: container-insights - match: - all: - - ($analyzer): - resource: - type: terraform-config - - (resource.aws_ecs_cluster && length(resource.aws_ecs_cluster) > `0`): true - assert: - all: - - message: ECS container insights are not enabled - check: - resource: - ~.(aws_ecs_cluster): - ~.(@): - (setting[?name == 'containerInsights']): - - value: enabled \ No newline at end of file