Skip to content

Commit

Permalink
add: kyverno-json-policies for terraform-best-practices for AWS ECS
Browse files Browse the repository at this point in the history
  • Loading branch information
fykaa committed Feb 7, 2024
1 parent dc52ca3 commit 7b8201d
Show file tree
Hide file tree
Showing 78 changed files with 8,696 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module "ecs_container_definition" {
source = "terraform-aws-modules/ecs/aws//modules/container-definition"
name = "example"
privileged = true
image = "public.ecr.aws/aws-containers/ecsdemo-frontend:776fd50"
port_mappings = [
{
name = "ecs-sample"
containerPort = 80
protocol = "tcp"
}
]

tags = {
Environment = "dev"
Terraform = "true"
}
}

# 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"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# ECS containers should run as non-privileged

It is important to ensure that ECS containers run without elevated privileges to enhance security. The policy checks the privileged parameter in the container definition and raises a concern if it is set to `true`. When a container is granted elevated permissions (similar to the root user) by having privileged set to true, it poses potential security risks on the host container instance.

It is advised against running containers with elevated privileges, as this may compromise the overall security of your ECS task definitions. It is recommended to avoid using privileged and, instead, specify precise privileges using specific parameters. This approach allows for a more controlled and secure execution environment, minimizing the risks associated with running containers with unnecessary elevated privileges.

### Policy Validation Testing Instructions

To evaluate and test the policy ensuring if the privileged parameter in the container definition is set to `false` (is default) in the Terraform plan payload, follow the steps outlined below:

For testing this policy you will need to:
- Make sure you have `kyverno-json` installed on the machine
- Properly authenticate with AWS

1. **Initialize Terraform:**
```bash
terraform init
```

2. **Create Binary Terraform Plan:**
```bash
terraform plan -out tfplan.binary
```

3. **Convert Binary to JSON Payload:**
```bash
terraform show -json tfplan.binary | jq > payload.json
```

4. **Test the Policy with Kyverno:**
```
kyverno-json scan --payload payload.json --policy policy.yaml
```

a. **Test Policy Against Valid Payload:**
```
kyverno-json scan --policy validate-ecs-containers-nonprivileged-in-resource.yaml --payload test/good-payload.json
```

This produces the output:
```
Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- validate-ecs-containers-nonprivileged-in-resource / validate-ecs-containers-nonprivileged-in-resource / PASSED
Done
```

b. **Test Against Invalid Payload:**
```
kyverno-json scan --policy validate-ecs-containers-nonprivileged-in-resource.yaml --payload test/bad-payload.json
```

This produces the output:
```
Loading policies ...
Loading payload ...
Pre processing ...
Running ( evaluating 1 resource against 1 policy ) ...
- validate-ecs-containers-nonprivileged-in-resource / validate-ecs-containers-nonprivileged-in-resource / FAILED: Containers `privileged` must be set to `false`.: any[0].check.~.(planned_values.root_module.resources[?type=='aws_ecs_task_definition'].values)[0].~.(json_parse(container_definitions))[0].privileged: Invalid value: true: Expected value: false; Privileged feild is not present. This is a valid Payload.: any[1].check.~.(planned_values.root_module.resources[?type=='aws_ecs_task_definition'].values)[0].~.(json_parse(container_definitions))[0].(!privileged): Invalid value: false: Expected value: true
Done
```

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
{
"format_version": "1.2",
"terraform_version": "1.7.1-dev",
"planned_values": {
"root_module": {
"resources": [
{
"address": "aws_ecs_task_definition.task",
"mode": "managed",
"type": "aws_ecs_task_definition",
"name": "task",
"provider_name": "registry.terraform.io/hashicorp/aws",
"schema_version": 1,
"values": {
"container_definitions": "[{\"cpu\":512,\"essential\":true,\"image\":\"nginx:1.23.1\",\"memory\":2048,\"name\":\"foo-task\",\"portMappings\":[{\"containerPort\":80,\"hostPort\":80}],\"privileged\":true,\"user\":\"xyz\"}]",
"cpu": null,
"ephemeral_storage": [],
"execution_role_arn": null,
"family": "service",
"inference_accelerator": [],
"ipc_mode": null,
"memory": null,
"pid_mode": null,
"placement_constraints": [],
"proxy_configuration": [],
"requires_compatibilities": null,
"runtime_platform": [],
"skip_destroy": false,
"tags": null,
"task_role_arn": null,
"volume": []
},
"sensitive_values": {
"ephemeral_storage": [],
"inference_accelerator": [],
"placement_constraints": [],
"proxy_configuration": [],
"runtime_platform": [],
"tags_all": {},
"volume": []
}
}
]
}
},
"resource_changes": [
{
"address": "aws_ecs_task_definition.task",
"mode": "managed",
"type": "aws_ecs_task_definition",
"name": "task",
"provider_name": "registry.terraform.io/hashicorp/aws",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"container_definitions": "[{\"cpu\":512,\"essential\":true,\"image\":\"nginx:1.23.1\",\"memory\":2048,\"name\":\"foo-task\",\"portMappings\":[{\"containerPort\":80,\"hostPort\":80}],\"privileged\":true,\"user\":\"xyz\"}]",
"cpu": null,
"ephemeral_storage": [],
"execution_role_arn": null,
"family": "service",
"inference_accelerator": [],
"ipc_mode": null,
"memory": null,
"pid_mode": null,
"placement_constraints": [],
"proxy_configuration": [],
"requires_compatibilities": null,
"runtime_platform": [],
"skip_destroy": false,
"tags": null,
"task_role_arn": null,
"volume": []
},
"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": []
},
"before_sensitive": false,
"after_sensitive": {
"ephemeral_storage": [],
"inference_accelerator": [],
"placement_constraints": [],
"proxy_configuration": [],
"runtime_platform": [],
"tags_all": {},
"volume": []
}
}
}
],
"configuration": {
"provider_config": {
"aws": {
"name": "aws",
"full_name": "registry.terraform.io/hashicorp/aws",
"version_constraint": "~> 4.0",
"expressions": {
"region": {
"constant_value": "us-west-1"
}
}
},
"docker": {
"name": "docker",
"full_name": "registry.terraform.io/kreuzwerker/docker",
"version_constraint": "~> 2.20.0"
}
},
"root_module": {
"resources": [
{
"address": "aws_ecs_task_definition.task",
"mode": "managed",
"type": "aws_ecs_task_definition",
"name": "task",
"provider_config_key": "aws",
"expressions": {
"container_definitions": {
"constant_value": " [\n {\n \"name\" : \"foo-task\",\n \"image\" : \"nginx:1.23.1\",\n \"cpu\" : 512,\n \"privileged\": true,\n \"user\" : \"xyz\",\n \"memory\" : 2048,\n \"essential\" : true,\n \"portMappings\" : [\n {\n \"containerPort\" : 80,\n \"hostPort\" : 80\n }\n ]\n }\n ]\n"
},
"family": {
"constant_value": "service"
}
},
"schema_version": 1
}
]
}
},
"timestamp": "2024-01-29T20:21:42Z",
"errored": false
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
resource "aws_ecs_task_definition" "task" {
family = "service"
container_definitions = <<DEFINITION
[
{
"name" : "foo-task",
"image" : "nginx:1.23.1",
"cpu" : 512,
"privileged": true,
"user" : "xyz",
"memory" : 2048,
"essential" : true,
"portMappings" : [
{
"containerPort" : 80,
"hostPort" : 80
}
]
}
]
DEFINITION
}

# 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"
}
Loading

0 comments on commit 7b8201d

Please sign in to comment.