Skip to content

Commit 81ae411

Browse files
authored
Merge pull request #8 from geekcell/ephemeral-storage
feat: Add managed storage encryption
2 parents 61d9630 + dcb1f24 commit 81ae411

File tree

4 files changed

+131
-13
lines changed

4 files changed

+131
-13
lines changed

README.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ performance and health.
4545
| Name | Description | Type | Default | Required |
4646
|------|-------------|------|---------|:--------:|
4747
| <a name="input_enable_container_insights"></a> [enable\_container\_insights](#input\_enable\_container\_insights) | Enable CloudWatch Container Insights for the cluster. | `bool` | `true` | no |
48+
| <a name="input_encrypt_ephemeral_storage"></a> [encrypt\_ephemeral\_storage](#input\_encrypt\_ephemeral\_storage) | Encrypt the ECS ephemeral storage for the cluster. | `bool` | `false` | no |
4849
| <a name="input_encrypt_execute_command_session"></a> [encrypt\_execute\_command\_session](#input\_encrypt\_execute\_command\_session) | Encrypt execute command session for the cluster. | `bool` | `false` | no |
50+
| <a name="input_encrypt_managed_storage"></a> [encrypt\_managed\_storage](#input\_encrypt\_managed\_storage) | Encrypt the ECS managed storage for the cluster. | `bool` | `false` | no |
4951
| <a name="input_logging_execute_command_session"></a> [logging\_execute\_command\_session](#input\_logging\_execute\_command\_session) | Log execute command session for the cluster. | `string` | `"DEFAULT"` | no |
5052
| <a name="input_name"></a> [name](#input\_name) | Name of the ECS cluster. | `string` | n/a | yes |
5153
| <a name="input_tags"></a> [tags](#input\_tags) | Tags to add to the ECS cluster. | `map(any)` | `{}` | no |
@@ -63,13 +65,15 @@ performance and health.
6365

6466
| Name | Version |
6567
|------|---------|
66-
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 4.36 |
68+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.59 |
6769

6870
## Resources
6971

70-
- resource.aws_cloudwatch_log_group.container_insights (main.tf#62)
71-
- resource.aws_cloudwatch_log_group.main (main.tf#55)
72+
- resource.aws_cloudwatch_log_group.container_insights (main.tf#80)
73+
- resource.aws_cloudwatch_log_group.main (main.tf#73)
7274
- resource.aws_ecs_cluster.main (main.tf#10)
75+
- data source.aws_caller_identity.current (main.tf#100)
76+
- data source.aws_iam_policy_document.kms_ephemeral (main.tf#101)
7377

7478
# Examples
7579
### Basic Example

main.tf

+111-9
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,40 @@ resource "aws_ecs_cluster" "main" {
2020
}
2121

2222
dynamic "configuration" {
23-
for_each = var.encrypt_execute_command_session || var.logging_execute_command_session != "DEFAULT" ? [true] : []
23+
for_each = (
24+
var.encrypt_execute_command_session ||
25+
var.logging_execute_command_session != "DEFAULT" ||
26+
var.encrypt_ephemeral_storage ||
27+
var.encrypt_managed_storage
28+
) ? [true] : []
2429

2530
content {
26-
execute_command_configuration {
27-
kms_key_id = var.encrypt_execute_command_session ? module.kms[0].key_id : null
28-
logging = var.logging_execute_command_session
31+
dynamic "execute_command_configuration" {
32+
for_each = var.encrypt_execute_command_session || var.logging_execute_command_session != "DEFAULT" ? [true] : []
2933

30-
dynamic "log_configuration" {
31-
for_each = var.logging_execute_command_session == "OVERRIDE" ? [true] : []
34+
content {
35+
kms_key_id = var.encrypt_execute_command_session ? module.kms[0].key_id : null
36+
logging = var.logging_execute_command_session
3237

33-
content {
34-
cloud_watch_encryption_enabled = false
35-
cloud_watch_log_group_name = aws_cloudwatch_log_group.main[0].name
38+
dynamic "log_configuration" {
39+
for_each = var.logging_execute_command_session == "OVERRIDE" ? [true] : []
40+
41+
content {
42+
cloud_watch_encryption_enabled = false
43+
cloud_watch_log_group_name = aws_cloudwatch_log_group.main[0].name
44+
}
3645
}
3746
}
3847
}
48+
49+
dynamic "managed_storage_configuration" {
50+
for_each = var.encrypt_ephemeral_storage || var.encrypt_managed_storage ? [true] : []
51+
52+
content {
53+
kms_key_id = var.encrypt_managed_storage ? module.kms[0].key_id : null
54+
fargate_ephemeral_storage_kms_key_id = var.encrypt_ephemeral_storage ? module.kms_ephemeral[0].key_id : null
55+
}
56+
}
3957
}
4058
}
4159

@@ -67,3 +85,87 @@ resource "aws_cloudwatch_log_group" "container_insights" {
6785

6886
tags = var.tags
6987
}
88+
89+
module "kms_ephemeral" {
90+
count = var.encrypt_ephemeral_storage || var.encrypt_managed_storage ? 1 : 0
91+
92+
source = "geekcell/kms/aws"
93+
version = ">= 1.0.0, < 2.0.0"
94+
policy = data.aws_iam_policy_document.kms_ephemeral[0].json
95+
96+
alias = "ecs/cluster/${var.name}/managed-storage"
97+
tags = var.tags
98+
}
99+
100+
data "aws_caller_identity" "current" {}
101+
data "aws_iam_policy_document" "kms_ephemeral" {
102+
count = var.encrypt_ephemeral_storage || var.encrypt_managed_storage ? 1 : 0
103+
104+
statement {
105+
sid = "Enable IAM User Permissions."
106+
effect = "Allow"
107+
actions = ["kms:*"]
108+
resources = ["*"]
109+
110+
principals {
111+
identifiers = ["*"]
112+
type = "AWS"
113+
}
114+
}
115+
116+
statement {
117+
sid = "Allow generate data key access for Fargate tasks."
118+
effect = "Allow"
119+
actions = ["kms:GenerateDataKeyWithoutPlaintext"]
120+
121+
principals {
122+
identifiers = ["fargate.amazonaws.com"]
123+
type = "Service"
124+
}
125+
126+
condition {
127+
test = "StringEquals"
128+
variable = "kms:EncryptionContext:aws:ecs:clusterAccount"
129+
values = [data.aws_caller_identity.current.account_id]
130+
}
131+
132+
condition {
133+
test = "StringEquals"
134+
variable = "kms:EncryptionContext:aws:ecs:clusterName"
135+
values = [var.name]
136+
}
137+
138+
resources = ["*"]
139+
}
140+
141+
statement {
142+
sid = "Allow grant creation permission for Fargate tasks."
143+
effect = "Allow"
144+
actions = ["kms:CreateGrant"]
145+
146+
principals {
147+
identifiers = ["fargate.amazonaws.com"]
148+
type = "Service"
149+
}
150+
151+
condition {
152+
test = "StringEquals"
153+
variable = "kms:EncryptionContext:aws:ecs:clusterAccount"
154+
values = [data.aws_caller_identity.current.account_id]
155+
}
156+
157+
condition {
158+
test = "StringEquals"
159+
variable = "kms:EncryptionContext:aws:ecs:clusterName"
160+
values = [var.name]
161+
}
162+
163+
condition {
164+
test = "ForAllValues:StringEquals"
165+
variable = "kms:GrantOperations"
166+
values = ["Decrypt"]
167+
}
168+
169+
resources = ["*"]
170+
}
171+
}

variables.tf

+12
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ variable "encrypt_execute_command_session" {
2323
type = bool
2424
}
2525

26+
variable "encrypt_ephemeral_storage" {
27+
description = "Encrypt the ECS ephemeral storage for the cluster."
28+
default = false
29+
type = bool
30+
}
31+
32+
variable "encrypt_managed_storage" {
33+
description = "Encrypt the ECS managed storage for the cluster."
34+
default = false
35+
type = bool
36+
}
37+
2638
variable "logging_execute_command_session" {
2739
description = "Log execute command session for the cluster."
2840
default = "DEFAULT"

versions.tf

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ terraform {
44
required_providers {
55
aws = {
66
source = "hashicorp/aws"
7-
version = ">= 4.36"
7+
version = ">= 5.59"
88
}
99
}
1010
}

0 commit comments

Comments
 (0)