diff --git a/pkg/commands/scan/command_test.go b/pkg/commands/scan/command_test.go index 9617def4..085d4b86 100644 --- a/pkg/commands/scan/command_test.go +++ b/pkg/commands/scan/command_test.go @@ -92,6 +92,41 @@ func Test_Execute(t *testing.T) { policies: []string{"../../../test/commands/scan/tf-ec2/policy.yaml"}, out: "../../../test/commands/scan/tf-ec2/out.txt", wantErr: false, + }, { + name: "tf-ecs-cluster-1", + payload: "../../../test/commands/scan/tf-ecs-cluster/payload.json", + preprocessors: []string{"planned_values.root_module.resources"}, + policies: []string{"../../../test/commands/scan/tf-ecs-cluster/01-policy.yaml"}, + out: "../../../test/commands/scan/tf-ecs-cluster/01-out.txt", + wantErr: false, + }, { + name: "tf-ecs-cluster-2", + payload: "../../../test/commands/scan/tf-ecs-cluster/payload.json", + preprocessors: []string{"planned_values.root_module.resources"}, + policies: []string{"../../../test/commands/scan/tf-ecs-cluster/02-policy.yaml"}, + out: "../../../test/commands/scan/tf-ecs-cluster/02-out.txt", + wantErr: false, + }, { + name: "tf-ecs-service-1", + payload: "../../../test/commands/scan/tf-ecs-service/payload.json", + preprocessors: []string{"planned_values.root_module.resources"}, + policies: []string{"../../../test/commands/scan/tf-ecs-service/01-policy.yaml"}, + out: "../../../test/commands/scan/tf-ecs-service/01-out.txt", + wantErr: false, + }, { + name: "tf-ecs-service-2", + payload: "../../../test/commands/scan/tf-ecs-service/payload.json", + preprocessors: []string{"planned_values.root_module.resources"}, + policies: []string{"../../../test/commands/scan/tf-ecs-service/02-policy.yaml"}, + out: "../../../test/commands/scan/tf-ecs-service/02-out.txt", + wantErr: false, + }, { + name: "tf-ecs-task-definition", + payload: "../../../test/commands/scan/tf-ecs-task-definition/payload.json", + preprocessors: []string{"planned_values.root_module.resources"}, + policies: []string{"../../../test/commands/scan/tf-ecs-task-definition/policy.yaml"}, + out: "../../../test/commands/scan/tf-ecs-task-definition/out.txt", + wantErr: false, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/test/commands/scan/tf-ecs-cluster/01-out.txt b/test/commands/scan/tf-ecs-cluster/01-out.txt new file mode 100644 index 00000000..e4c207af --- /dev/null +++ b/test/commands/scan/tf-ecs-cluster/01-out.txt @@ -0,0 +1,6 @@ +Loading policies ... +Loading payload ... +Pre processing ... +Running ( evaluating 3 resources against 1 policy ) ... +- required-container-insights / required-container-insights / (unknown) PASSED +Done diff --git a/test/commands/scan/tf-ecs-cluster/01-policy.yaml b/test/commands/scan/tf-ecs-cluster/01-policy.yaml new file mode 100644 index 00000000..2dea5949 --- /dev/null +++ b/test/commands/scan/tf-ecs-cluster/01-policy.yaml @@ -0,0 +1,20 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: required-container-insights +spec: + rules: + - name: required-container-insights + match: + any: + - type: aws_ecs_cluster + assert: + all: + - message: "Container insights should be enabled on ECS cluster" + check: + values: + ~.setting: + name: containerInsights + value: enabled + + diff --git a/test/commands/scan/tf-ecs-cluster/02-out.txt b/test/commands/scan/tf-ecs-cluster/02-out.txt new file mode 100644 index 00000000..100d0b88 --- /dev/null +++ b/test/commands/scan/tf-ecs-cluster/02-out.txt @@ -0,0 +1,6 @@ +Loading policies ... +Loading payload ... +Pre processing ... +Running ( evaluating 3 resources against 1 policy ) ... +- ecs-cluster-enable-logging / ecs-cluster-enable-logging / (unknown) PASSED +Done diff --git a/test/commands/scan/tf-ecs-cluster/02-policy.yaml b/test/commands/scan/tf-ecs-cluster/02-policy.yaml new file mode 100644 index 00000000..cfa0a5c7 --- /dev/null +++ b/test/commands/scan/tf-ecs-cluster/02-policy.yaml @@ -0,0 +1,21 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: ecs-cluster-enable-logging +spec: + rules: + - name: ecs-cluster-enable-logging + match: + any: + - type: aws_ecs_cluster + context: + - name: forbidden_values + variable: ["NONE"] + assert: + all: + - message: "ECS Cluster should enable logging of ECS Exec" + check: + values: + ~.configuration: + ~.execute_command_configuration: + (contains($forbidden_values, @.logging)): false diff --git a/test/commands/scan/tf-ecs-cluster/main.tf b/test/commands/scan/tf-ecs-cluster/main.tf new file mode 100644 index 00000000..938a67aa --- /dev/null +++ b/test/commands/scan/tf-ecs-cluster/main.tf @@ -0,0 +1,29 @@ +resource "aws_kms_key" "example" { + description = "example" + deletion_window_in_days = 7 +} + +resource "aws_cloudwatch_log_group" "example" { + name = "example" +} + +resource "aws_ecs_cluster" "test" { + name = "example" + + configuration { + execute_command_configuration { + kms_key_id = aws_kms_key.example.arn + logging = "OVERRIDE" + + log_configuration { + cloud_watch_encryption_enabled = true + cloud_watch_log_group_name = aws_cloudwatch_log_group.example.name + } + } + } + + setting { + name = "containerInsights" + value = "enabled" + } +} \ No newline at end of file diff --git a/test/commands/scan/tf-ecs-cluster/payload.json b/test/commands/scan/tf-ecs-cluster/payload.json new file mode 100644 index 00000000..142e0183 --- /dev/null +++ b/test/commands/scan/tf-ecs-cluster/payload.json @@ -0,0 +1,365 @@ +{ + "format_version": "1.2", + "terraform_version": "1.6.0", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "aws_cloudwatch_log_group.example", + "mode": "managed", + "type": "aws_cloudwatch_log_group", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "kms_key_id": null, + "name": "example", + "retention_in_days": 0, + "skip_destroy": false, + "tags": null + }, + "sensitive_values": { + "tags_all": {} + } + }, + { + "address": "aws_ecs_cluster.test", + "mode": "managed", + "type": "aws_ecs_cluster", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "configuration": [ + { + "execute_command_configuration": [ + { + "log_configuration": [ + { + "cloud_watch_encryption_enabled": true, + "cloud_watch_log_group_name": "example", + "s3_bucket_encryption_enabled": null, + "s3_bucket_name": null, + "s3_key_prefix": null + } + ], + "logging": "OVERRIDE" + } + ] + } + ], + "name": "example", + "service_connect_defaults": [], + "setting": [ + { + "name": "containerInsights", + "value": "enabled" + } + ], + "tags": null + }, + "sensitive_values": { + "configuration": [ + { + "execute_command_configuration": [ + { + "log_configuration": [ + {} + ] + } + ] + } + ], + "service_connect_defaults": [], + "setting": [ + {} + ], + "tags_all": {} + } + }, + { + "address": "aws_kms_key.example", + "mode": "managed", + "type": "aws_kms_key", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "bypass_policy_lockout_safety_check": false, + "custom_key_store_id": null, + "customer_master_key_spec": "SYMMETRIC_DEFAULT", + "deletion_window_in_days": 7, + "description": "example", + "enable_key_rotation": false, + "is_enabled": true, + "key_usage": "ENCRYPT_DECRYPT", + "tags": null + }, + "sensitive_values": { + "tags_all": {} + } + } + ] + } + }, + "resource_changes": [ + { + "address": "aws_cloudwatch_log_group.example", + "mode": "managed", + "type": "aws_cloudwatch_log_group", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "kms_key_id": null, + "name": "example", + "retention_in_days": 0, + "skip_destroy": false, + "tags": null + }, + "after_unknown": { + "arn": true, + "id": true, + "name_prefix": true, + "tags_all": true + }, + "before_sensitive": false, + "after_sensitive": { + "tags_all": {} + } + } + }, + { + "address": "aws_ecs_cluster.test", + "mode": "managed", + "type": "aws_ecs_cluster", + "name": "test", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "configuration": [ + { + "execute_command_configuration": [ + { + "log_configuration": [ + { + "cloud_watch_encryption_enabled": true, + "cloud_watch_log_group_name": "example", + "s3_bucket_encryption_enabled": null, + "s3_bucket_name": null, + "s3_key_prefix": null + } + ], + "logging": "OVERRIDE" + } + ] + } + ], + "name": "example", + "service_connect_defaults": [], + "setting": [ + { + "name": "containerInsights", + "value": "enabled" + } + ], + "tags": null + }, + "after_unknown": { + "arn": true, + "configuration": [ + { + "execute_command_configuration": [ + { + "kms_key_id": true, + "log_configuration": [ + {} + ] + } + ] + } + ], + "id": true, + "service_connect_defaults": [], + "setting": [ + {} + ], + "tags_all": true + }, + "before_sensitive": false, + "after_sensitive": { + "configuration": [ + { + "execute_command_configuration": [ + { + "log_configuration": [ + {} + ] + } + ] + } + ], + "service_connect_defaults": [], + "setting": [ + {} + ], + "tags_all": {} + } + } + }, + { + "address": "aws_kms_key.example", + "mode": "managed", + "type": "aws_kms_key", + "name": "example", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "bypass_policy_lockout_safety_check": false, + "custom_key_store_id": null, + "customer_master_key_spec": "SYMMETRIC_DEFAULT", + "deletion_window_in_days": 7, + "description": "example", + "enable_key_rotation": false, + "is_enabled": true, + "key_usage": "ENCRYPT_DECRYPT", + "tags": null + }, + "after_unknown": { + "arn": true, + "id": true, + "key_id": true, + "multi_region": true, + "policy": true, + "tags_all": true + }, + "before_sensitive": false, + "after_sensitive": { + "tags_all": {} + } + } + } + ], + "configuration": { + "provider_config": { + "aws": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws" + } + }, + "root_module": { + "resources": [ + { + "address": "aws_cloudwatch_log_group.example", + "mode": "managed", + "type": "aws_cloudwatch_log_group", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "name": { + "constant_value": "example" + } + }, + "schema_version": 0 + }, + { + "address": "aws_ecs_cluster.test", + "mode": "managed", + "type": "aws_ecs_cluster", + "name": "test", + "provider_config_key": "aws", + "expressions": { + "configuration": [ + { + "execute_command_configuration": [ + { + "kms_key_id": { + "references": [ + "aws_kms_key.example.arn", + "aws_kms_key.example" + ] + }, + "log_configuration": [ + { + "cloud_watch_encryption_enabled": { + "constant_value": true + }, + "cloud_watch_log_group_name": { + "references": [ + "aws_cloudwatch_log_group.example.name", + "aws_cloudwatch_log_group.example" + ] + } + } + ], + "logging": { + "constant_value": "OVERRIDE" + } + } + ] + } + ], + "name": { + "constant_value": "example" + }, + "setting": [ + { + "name": { + "constant_value": "containerInsights" + }, + "value": { + "constant_value": "enabled" + } + } + ] + }, + "schema_version": 0 + }, + { + "address": "aws_kms_key.example", + "mode": "managed", + "type": "aws_kms_key", + "name": "example", + "provider_config_key": "aws", + "expressions": { + "deletion_window_in_days": { + "constant_value": 7 + }, + "description": { + "constant_value": "example" + } + }, + "schema_version": 0 + } + ] + } + }, + "relevant_attributes": [ + { + "resource": "aws_kms_key.example", + "attribute": [ + "arn" + ] + }, + { + "resource": "aws_cloudwatch_log_group.example", + "attribute": [ + "name" + ] + } + ], + "timestamp": "2023-10-05T08:06:11Z", + "errored": false +} diff --git a/test/commands/scan/tf-ecs-service/01-out.txt b/test/commands/scan/tf-ecs-service/01-out.txt new file mode 100644 index 00000000..2f02a225 --- /dev/null +++ b/test/commands/scan/tf-ecs-service/01-out.txt @@ -0,0 +1,6 @@ +Loading policies ... +Loading payload ... +Pre processing ... +Running ( evaluating 1 resource against 1 policy ) ... +- required-latest-platform-fargate / required-latest-platform / (unknown) PASSED +Done diff --git a/test/commands/scan/tf-ecs-service/01-policy.yaml b/test/commands/scan/tf-ecs-service/01-policy.yaml new file mode 100644 index 00000000..3f0454a8 --- /dev/null +++ b/test/commands/scan/tf-ecs-service/01-policy.yaml @@ -0,0 +1,21 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: required-latest-platform-fargate +spec: + rules: + - name: required-latest-platform + match: + any: + - type: aws_ecs_service + values: + launch_type: FARGATE + context: + - name: pv + variable: platform_version + assert: + all: + - message: "ECS Fargate services should run on the latest Fargate platform version" + check: + values: + platform_version: 'LATEST' \ No newline at end of file diff --git a/test/commands/scan/tf-ecs-service/02-out.txt b/test/commands/scan/tf-ecs-service/02-out.txt new file mode 100644 index 00000000..bf30d5cd --- /dev/null +++ b/test/commands/scan/tf-ecs-service/02-out.txt @@ -0,0 +1,6 @@ +Loading policies ... +Loading payload ... +Pre processing ... +Running ( evaluating 1 resource against 1 policy ) ... +- ecs-public-ip / ecs-public-ip / (unknown) PASSED +Done diff --git a/test/commands/scan/tf-ecs-service/02-policy.yaml b/test/commands/scan/tf-ecs-service/02-policy.yaml new file mode 100644 index 00000000..c10d073b --- /dev/null +++ b/test/commands/scan/tf-ecs-service/02-policy.yaml @@ -0,0 +1,20 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: ecs-public-ip +spec: + rules: + - name: ecs-public-ip + match: + any: + - type: aws_ecs_service + context: + - name: allowed-values + variable: [false] + assert: + all: + - message: "ECS services should not have public IP addresses assigned to them automatically" + check: + values: + ~.network_configuration: + (contains('$allowed-values', @.assign_public_ip)): false \ No newline at end of file diff --git a/test/commands/scan/tf-ecs-service/main.tf b/test/commands/scan/tf-ecs-service/main.tf new file mode 100644 index 00000000..fb84fa07 --- /dev/null +++ b/test/commands/scan/tf-ecs-service/main.tf @@ -0,0 +1,38 @@ +provider "aws" { + region = "eu-west-1" + skip_credentials_validation = true + skip_requesting_account_id = true + skip_metadata_api_check = true + access_key = "mock_access_key" + secret_key = "mock_secret_key" +} + +resource "aws_ecs_service" "mongo" { + name = "mongodb" + cluster = "id" + task_definition = "aws_arn" + desired_count = 3 + + ordered_placement_strategy { + type = "binpack" + field = "cpu" + } + + load_balancer { + container_name = "mongo" + container_port = 8080 + } + + network_configuration { + subnets = ["subnet-abcde012", "subnet-bcde012a", "subnet-fghi345a"] + assign_public_ip = true + } + + launch_type = "FARGATE" + platform_version = "LATEST" + + placement_constraints { + type = "memberOf" + expression = "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]" + } +} \ No newline at end of file diff --git a/test/commands/scan/tf-ecs-service/payload.json b/test/commands/scan/tf-ecs-service/payload.json new file mode 100644 index 00000000..d9bd6df0 --- /dev/null +++ b/test/commands/scan/tf-ecs-service/payload.json @@ -0,0 +1,338 @@ +{ + "format_version": "1.2", + "terraform_version": "1.6.0", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "aws_ecs_service.mongo", + "mode": "managed", + "type": "aws_ecs_service", + "name": "mongo", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 0, + "values": { + "alarms": [], + "capacity_provider_strategy": [], + "cluster": "id", + "deployment_circuit_breaker": [], + "deployment_controller": [], + "deployment_maximum_percent": 200, + "deployment_minimum_healthy_percent": 100, + "desired_count": 3, + "enable_ecs_managed_tags": false, + "enable_execute_command": false, + "force_new_deployment": null, + "health_check_grace_period_seconds": null, + "launch_type": "FARGATE", + "load_balancer": [ + { + "container_name": "mongo", + "container_port": 8080, + "elb_name": "", + "target_group_arn": "" + } + ], + "name": "mongodb", + "network_configuration": [ + { + "assign_public_ip": true, + "security_groups": null, + "subnets": [ + "subnet-abcde012", + "subnet-bcde012a", + "subnet-fghi345a" + ] + } + ], + "ordered_placement_strategy": [ + { + "field": "cpu", + "type": "binpack" + } + ], + "placement_constraints": [ + { + "expression": "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]", + "type": "memberOf" + } + ], + "platform_version": "LATEST", + "propagate_tags": null, + "scheduling_strategy": "REPLICA", + "service_connect_configuration": [], + "service_registries": [], + "tags": null, + "task_definition": "aws_arn", + "timeouts": null, + "wait_for_steady_state": false + }, + "sensitive_values": { + "alarms": [], + "capacity_provider_strategy": [], + "deployment_circuit_breaker": [], + "deployment_controller": [], + "load_balancer": [ + {} + ], + "network_configuration": [ + { + "subnets": [ + false, + false, + false + ] + } + ], + "ordered_placement_strategy": [ + {} + ], + "placement_constraints": [ + {} + ], + "service_connect_configuration": [], + "service_registries": [], + "tags_all": {}, + "triggers": {} + } + } + ] + } + }, + "resource_changes": [ + { + "address": "aws_ecs_service.mongo", + "mode": "managed", + "type": "aws_ecs_service", + "name": "mongo", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "alarms": [], + "capacity_provider_strategy": [], + "cluster": "id", + "deployment_circuit_breaker": [], + "deployment_controller": [], + "deployment_maximum_percent": 200, + "deployment_minimum_healthy_percent": 100, + "desired_count": 3, + "enable_ecs_managed_tags": false, + "enable_execute_command": false, + "force_new_deployment": null, + "health_check_grace_period_seconds": null, + "launch_type": "FARGATE", + "load_balancer": [ + { + "container_name": "mongo", + "container_port": 8080, + "elb_name": "", + "target_group_arn": "" + } + ], + "name": "mongodb", + "network_configuration": [ + { + "assign_public_ip": true, + "security_groups": null, + "subnets": [ + "subnet-abcde012", + "subnet-bcde012a", + "subnet-fghi345a" + ] + } + ], + "ordered_placement_strategy": [ + { + "field": "cpu", + "type": "binpack" + } + ], + "placement_constraints": [ + { + "expression": "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]", + "type": "memberOf" + } + ], + "platform_version": "LATEST", + "propagate_tags": null, + "scheduling_strategy": "REPLICA", + "service_connect_configuration": [], + "service_registries": [], + "tags": null, + "task_definition": "aws_arn", + "timeouts": null, + "wait_for_steady_state": false + }, + "after_unknown": { + "alarms": [], + "capacity_provider_strategy": [], + "deployment_circuit_breaker": [], + "deployment_controller": [], + "iam_role": true, + "id": true, + "load_balancer": [ + {} + ], + "network_configuration": [ + { + "subnets": [ + false, + false, + false + ] + } + ], + "ordered_placement_strategy": [ + {} + ], + "placement_constraints": [ + {} + ], + "service_connect_configuration": [], + "service_registries": [], + "tags_all": true, + "triggers": true + }, + "before_sensitive": false, + "after_sensitive": { + "alarms": [], + "capacity_provider_strategy": [], + "deployment_circuit_breaker": [], + "deployment_controller": [], + "load_balancer": [ + {} + ], + "network_configuration": [ + { + "subnets": [ + false, + false, + false + ] + } + ], + "ordered_placement_strategy": [ + {} + ], + "placement_constraints": [ + {} + ], + "service_connect_configuration": [], + "service_registries": [], + "tags_all": {}, + "triggers": {} + } + } + } + ], + "configuration": { + "provider_config": { + "aws": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws", + "expressions": { + "access_key": { + "constant_value": "mock_access_key" + }, + "region": { + "constant_value": "eu-west-1" + }, + "secret_key": { + "constant_value": "mock_secret_key" + }, + "skip_credentials_validation": { + "constant_value": true + }, + "skip_metadata_api_check": { + "constant_value": true + }, + "skip_requesting_account_id": { + "constant_value": true + } + } + } + }, + "root_module": { + "resources": [ + { + "address": "aws_ecs_service.mongo", + "mode": "managed", + "type": "aws_ecs_service", + "name": "mongo", + "provider_config_key": "aws", + "expressions": { + "cluster": { + "constant_value": "id" + }, + "desired_count": { + "constant_value": 3 + }, + "launch_type": { + "constant_value": "FARGATE" + }, + "load_balancer": [ + { + "container_name": { + "constant_value": "mongo" + }, + "container_port": { + "constant_value": 8080 + } + } + ], + "name": { + "constant_value": "mongodb" + }, + "network_configuration": [ + { + "assign_public_ip": { + "constant_value": true + }, + "subnets": { + "constant_value": [ + "subnet-abcde012", + "subnet-bcde012a", + "subnet-fghi345a" + ] + } + } + ], + "ordered_placement_strategy": [ + { + "field": { + "constant_value": "cpu" + }, + "type": { + "constant_value": "binpack" + } + } + ], + "placement_constraints": [ + { + "expression": { + "constant_value": "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]" + }, + "type": { + "constant_value": "memberOf" + } + } + ], + "platform_version": { + "constant_value": "LATEST" + }, + "task_definition": { + "constant_value": "aws_arn" + } + }, + "schema_version": 0 + } + ] + } + }, + "timestamp": "2023-10-05T12:30:36Z", + "errored": false +} diff --git a/test/commands/scan/tf-ecs-task-definition/main.tf b/test/commands/scan/tf-ecs-task-definition/main.tf new file mode 100644 index 00000000..b96f5505 --- /dev/null +++ b/test/commands/scan/tf-ecs-task-definition/main.tf @@ -0,0 +1,43 @@ +resource "aws_ecs_task_definition" "service" { + family = "service" + container_definitions = jsonencode([ + { + name = "first" + image = "service-first" + cpu = 10 + memory = 512 + essential = true + readonlyRootFilesystem = true + portMappings = [ + { + containerPort = 80 + hostPort = 80 + } + ] + }, + { + name = "second" + image = "service-second" + cpu = 10 + memory = 256 + essential = true + readonlyRootFilesystem = true + portMappings = [ + { + containerPort = 443 + hostPort = 443 + } + ] + } + ]) + + volume { + name = "service-storage" + host_path = "/ecs/service-storage" + } + + placement_constraints { + type = "memberOf" + expression = "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]" + } +} \ No newline at end of file diff --git a/test/commands/scan/tf-ecs-task-definition/out.txt b/test/commands/scan/tf-ecs-task-definition/out.txt new file mode 100644 index 00000000..5d119097 --- /dev/null +++ b/test/commands/scan/tf-ecs-task-definition/out.txt @@ -0,0 +1,6 @@ +Loading policies ... +Loading payload ... +Pre processing ... +Running ( evaluating 1 resource against 1 policy ) ... +- required-s3-tags / require-team-tag / (unknown) PASSED +Done diff --git a/test/commands/scan/tf-ecs-task-definition/payload.json b/test/commands/scan/tf-ecs-task-definition/payload.json new file mode 100644 index 00000000..898200b5 --- /dev/null +++ b/test/commands/scan/tf-ecs-task-definition/payload.json @@ -0,0 +1,202 @@ +{ + "format_version": "1.2", + "terraform_version": "1.6.0", + "planned_values": { + "root_module": { + "resources": [ + { + "address": "aws_ecs_task_definition.service", + "mode": "managed", + "type": "aws_ecs_task_definition", + "name": "service", + "provider_name": "registry.terraform.io/hashicorp/aws", + "schema_version": 1, + "values": { + "container_definitions": "[{\"cpu\":10,\"essential\":true,\"image\":\"service-first\",\"memory\":512,\"name\":\"first\",\"portMappings\":[{\"containerPort\":80,\"hostPort\":80}],\"readonlyRootFilesystem\":true},{\"cpu\":10,\"essential\":true,\"image\":\"service-second\",\"memory\":256,\"name\":\"second\",\"portMappings\":[{\"containerPort\":443,\"hostPort\":443}],\"readonlyRootFilesystem\":true}]", + "cpu": null, + "ephemeral_storage": [], + "execution_role_arn": null, + "family": "service", + "inference_accelerator": [], + "ipc_mode": null, + "memory": null, + "pid_mode": null, + "placement_constraints": [ + { + "expression": "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]", + "type": "memberOf" + } + ], + "proxy_configuration": [], + "requires_compatibilities": null, + "runtime_platform": [], + "skip_destroy": false, + "tags": null, + "task_role_arn": null, + "volume": [ + { + "docker_volume_configuration": [], + "efs_volume_configuration": [], + "fsx_windows_file_server_volume_configuration": [], + "host_path": "/ecs/service-storage", + "name": "service-storage" + } + ] + }, + "sensitive_values": { + "ephemeral_storage": [], + "inference_accelerator": [], + "placement_constraints": [ + {} + ], + "proxy_configuration": [], + "runtime_platform": [], + "tags_all": {}, + "volume": [ + { + "docker_volume_configuration": [], + "efs_volume_configuration": [], + "fsx_windows_file_server_volume_configuration": [] + } + ] + } + } + ] + } + }, + "resource_changes": [ + { + "address": "aws_ecs_task_definition.service", + "mode": "managed", + "type": "aws_ecs_task_definition", + "name": "service", + "provider_name": "registry.terraform.io/hashicorp/aws", + "change": { + "actions": [ + "create" + ], + "before": null, + "after": { + "container_definitions": "[{\"cpu\":10,\"essential\":true,\"image\":\"service-first\",\"memory\":512,\"name\":\"first\",\"portMappings\":[{\"containerPort\":80,\"hostPort\":80}],\"readonlyRootFilesystem\":true},{\"cpu\":10,\"essential\":true,\"image\":\"service-second\",\"memory\":256,\"name\":\"second\",\"portMappings\":[{\"containerPort\":443,\"hostPort\":443}],\"readonlyRootFilesystem\":true}]", + "cpu": null, + "ephemeral_storage": [], + "execution_role_arn": null, + "family": "service", + "inference_accelerator": [], + "ipc_mode": null, + "memory": null, + "pid_mode": null, + "placement_constraints": [ + { + "expression": "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]", + "type": "memberOf" + } + ], + "proxy_configuration": [], + "requires_compatibilities": null, + "runtime_platform": [], + "skip_destroy": false, + "tags": null, + "task_role_arn": null, + "volume": [ + { + "docker_volume_configuration": [], + "efs_volume_configuration": [], + "fsx_windows_file_server_volume_configuration": [], + "host_path": "/ecs/service-storage", + "name": "service-storage" + } + ] + }, + "after_unknown": { + "arn": true, + "arn_without_revision": true, + "ephemeral_storage": [], + "id": true, + "inference_accelerator": [], + "network_mode": true, + "placement_constraints": [ + {} + ], + "proxy_configuration": [], + "revision": true, + "runtime_platform": [], + "tags_all": true, + "volume": [ + { + "docker_volume_configuration": [], + "efs_volume_configuration": [], + "fsx_windows_file_server_volume_configuration": [] + } + ] + }, + "before_sensitive": false, + "after_sensitive": { + "ephemeral_storage": [], + "inference_accelerator": [], + "placement_constraints": [ + {} + ], + "proxy_configuration": [], + "runtime_platform": [], + "tags_all": {}, + "volume": [ + { + "docker_volume_configuration": [], + "efs_volume_configuration": [], + "fsx_windows_file_server_volume_configuration": [] + } + ] + } + } + } + ], + "configuration": { + "provider_config": { + "aws": { + "name": "aws", + "full_name": "registry.terraform.io/hashicorp/aws" + } + }, + "root_module": { + "resources": [ + { + "address": "aws_ecs_task_definition.service", + "mode": "managed", + "type": "aws_ecs_task_definition", + "name": "service", + "provider_config_key": "aws", + "expressions": { + "container_definitions": {}, + "family": { + "constant_value": "service" + }, + "placement_constraints": [ + { + "expression": { + "constant_value": "attribute:ecs.availability-zone in [us-west-2a, us-west-2b]" + }, + "type": { + "constant_value": "memberOf" + } + } + ], + "volume": [ + { + "host_path": { + "constant_value": "/ecs/service-storage" + }, + "name": { + "constant_value": "service-storage" + } + } + ] + }, + "schema_version": 1 + } + ] + } + }, + "timestamp": "2023-10-05T08:11:25Z", + "errored": false +} diff --git a/test/commands/scan/tf-ecs-task-definition/policy.yaml b/test/commands/scan/tf-ecs-task-definition/policy.yaml new file mode 100644 index 00000000..7e402dae --- /dev/null +++ b/test/commands/scan/tf-ecs-task-definition/policy.yaml @@ -0,0 +1,18 @@ +apiVersion: json.kyverno.io/v1alpha1 +kind: ValidatingPolicy +metadata: + name: required-s3-tags +spec: + rules: + - name: require-team-tag + match: + any: + - type: aws_ecs_task_definition + assert: + any: + - message: ECS containers only have read-only access to root filesystems + check: + values: + ~.(json_parse(container_definitions)): + readonlyRootFilesystem: true +