Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added kyverno-json-policies for terraform-best-practices (AWS ECS) #112

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading