Skip to content

Commit 116942d

Browse files
authored
adds support for injection of secrets from ssm parameter store (#34)
1 parent 3072435 commit 116942d

File tree

4 files changed

+214
-3
lines changed

4 files changed

+214
-3
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ that is needed.
3939
| [autoscale-perf.tf][edap] | Performance-based auto scaling | Yes |
4040
| [autoscale-time.tf][edat] | Time-based auto scaling | Yes |
4141
| [logs-logzio.tf][edll] | Ship container logs to logz.io | Yes |
42-
| [secretsmanager.tf][edsm] | Add a base secret to Secretsmanager | Yes |
42+
| [secretsmanager.tf][edsm] | Add a Secrets Manager secret with a CMK KMS key. Also gives app role and ECS task definition role access to read secrets from Secrets Manager | Yes |
43+
| [ssm-parameters.tf][ssm] | Add a CMK KMS key for use with SSM Parameter Store. Also gives ECS task definition role access to read secrets from parameter store. | Yes |
4344
| [ecs-event-stream.tf][ees] | Add an ECS event log dashboard | Yes |
4445

4546

@@ -136,6 +137,7 @@ $ fargate-create -f terraform.tfvars
136137
[edat]: ./env/dev/autoscale-time.tf
137138
[edll]: ./env/dev/logs-logzio.tf
138139
[edsm]: ./env/dev/secretsmanager.tf
140+
[ssm]: ./env/dev/ssm-parameters.tf
139141
[ees]: ./env/dev/ecs-event-stream.tf
140142
[base]: ./base/README.md
141143
[env-dev]: ./env/dev/README.md

env/dev/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ The optional components can be removed by simply deleting the `.tf` file.
2020
| [autoscale-perf.tf][edap] | Performance-based auto scaling | Yes |
2121
| [autoscale-time.tf][edat] | Time-based auto scaling | Yes |
2222
| [logs-logzio.tf][edll] | Ship container logs to logz.io | Yes |
23-
| [secretsmanager.tf][edsm] | Add a base secret to Secretsmanager | Yes |
23+
| [secretsmanager.tf][edsm] | Add a Secrets Manager secret with a CMK KMS key. Also gives app role and ECS task definition role access to read secrets from Secrets Manager | Yes |
24+
| [ssm-parameters.tf][ssm] | Add a CMK KMS key for use with SSM Parameter Store. Also gives ECS task definition role access to read secrets from parameter store. | Yes |
25+
2426

2527

2628
## Usage
@@ -103,3 +105,4 @@ $ terraform apply
103105
[edsm]: secretsmanager.tf
104106
[alb-docs]: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/application-load-balancers.html
105107
[up]: https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html
108+
[ssm]: ssm-parameters.tf

env/dev/fargate-create.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,16 @@ prompts:
3030
- "logs-logzio.tf"
3131
- "logs-logzio.zip"
3232

33-
- question: "Would you like an integrated Secrets Manager secret?"
33+
- question: "Would you like to use Secrets Manager for secrets?"
3434
default: "no"
3535
filesToDeleteIfNo:
3636
- "secretsmanager.tf"
3737

38+
- question: "Would you like to use SSM Parameter Store for secrets?"
39+
default: "no"
40+
filesToDeleteIfNo:
41+
- "ssm-parameters.tf"
42+
3843
- question: "Would you like an ECS event log dashboard?"
3944
default: "yes"
4045
filesToDeleteIfNo:

env/dev/ssm-parameters.tf

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
locals {
2+
# KMS write actions
3+
kms_write_actions = [
4+
"kms:CancelKeyDeletion",
5+
"kms:CreateAlias",
6+
"kms:CreateGrant",
7+
"kms:CreateKey",
8+
"kms:DeleteAlias",
9+
"kms:DeleteImportedKeyMaterial",
10+
"kms:DisableKey",
11+
"kms:DisableKeyRotation",
12+
"kms:EnableKey",
13+
"kms:EnableKeyRotation",
14+
"kms:Encrypt",
15+
"kms:GenerateDataKey",
16+
"kms:GenerateDataKeyWithoutPlaintext",
17+
"kms:GenerateRandom",
18+
"kms:GetKeyPolicy",
19+
"kms:GetKeyRotationStatus",
20+
"kms:GetParametersForImport",
21+
"kms:ImportKeyMaterial",
22+
"kms:PutKeyPolicy",
23+
"kms:ReEncryptFrom",
24+
"kms:ReEncryptTo",
25+
"kms:RetireGrant",
26+
"kms:RevokeGrant",
27+
"kms:ScheduleKeyDeletion",
28+
"kms:TagResource",
29+
"kms:UntagResource",
30+
"kms:UpdateAlias",
31+
"kms:UpdateKeyDescription",
32+
]
33+
34+
# KMS read actions
35+
kms_read_actions = [
36+
"kms:Decrypt",
37+
"kms:DescribeKey",
38+
"kms:List*",
39+
]
40+
41+
# list of saml users for policies
42+
saml_user_ids = flatten([
43+
data.aws_caller_identity.current.user_id,
44+
data.aws_caller_identity.current.account_id,
45+
formatlist(
46+
"%s:%s",
47+
data.aws_iam_role.saml_role_ssm.unique_id,
48+
var.secrets_saml_users,
49+
),
50+
])
51+
52+
# list of role users and saml users for policies
53+
role_and_saml_ids = flatten([
54+
"${aws_iam_role.ecsTaskExecutionRole.unique_id}:*",
55+
local.saml_user_ids,
56+
])
57+
58+
sm_arn = "arn:aws:secretsmanager:${var.region}:${data.aws_caller_identity.current.account_id}:secret:${var.app}-${var.environment}-??????"
59+
}
60+
61+
# get the saml user info so we can get the unique_id
62+
data "aws_iam_role" "saml_role_ssm" {
63+
name = var.saml_role
64+
}
65+
66+
# The users (email addresses) from the saml role to give access
67+
# case sensitive
68+
variable "secrets_saml_users" {
69+
type = list(string)
70+
}
71+
72+
# kms key used to encrypt ssm parameters
73+
resource "aws_kms_key" "ssm" {
74+
description = "ssm parameters key for ${var.app}-${var.environment}"
75+
deletion_window_in_days = 7
76+
enable_key_rotation = true
77+
tags = var.tags
78+
policy = data.aws_iam_policy_document.ssm.json
79+
}
80+
81+
resource "aws_kms_alias" "ssm" {
82+
name = "alias/${var.app}-${var.environment}"
83+
target_key_id = "${aws_kms_key.ssm.id}"
84+
}
85+
86+
data "aws_iam_policy_document" "ssm" {
87+
statement {
88+
sid = "DenyWriteToAllExceptSAMLUsers"
89+
effect = "Deny"
90+
91+
principals {
92+
type = "AWS"
93+
identifiers = ["*"]
94+
}
95+
96+
actions = local.kms_write_actions
97+
resources = ["*"]
98+
99+
condition {
100+
test = "StringNotLike"
101+
variable = "aws:userId"
102+
values = local.saml_user_ids
103+
}
104+
}
105+
106+
statement {
107+
sid = "DenyReadToAllExceptRoleAndSAMLUsers"
108+
effect = "Deny"
109+
110+
principals {
111+
type = "AWS"
112+
identifiers = ["*"]
113+
}
114+
115+
actions = local.kms_read_actions
116+
resources = ["*"]
117+
118+
condition {
119+
test = "StringNotLike"
120+
variable = "aws:userId"
121+
values = local.role_and_saml_ids
122+
}
123+
}
124+
125+
statement {
126+
sid = "AllowWriteToSAMLUsers"
127+
effect = "Allow"
128+
129+
principals {
130+
type = "AWS"
131+
identifiers = ["*"]
132+
}
133+
134+
actions = local.kms_write_actions
135+
resources = ["*"]
136+
137+
condition {
138+
test = "StringLike"
139+
variable = "aws:userId"
140+
values = local.saml_user_ids
141+
}
142+
}
143+
144+
statement {
145+
sid = "AllowReadRoleAndSAMLUsers"
146+
effect = "Allow"
147+
148+
principals {
149+
type = "AWS"
150+
identifiers = ["*"]
151+
}
152+
153+
actions = local.kms_read_actions
154+
resources = ["*"]
155+
156+
condition {
157+
test = "StringLike"
158+
variable = "aws:userId"
159+
values = local.role_and_saml_ids
160+
}
161+
}
162+
}
163+
164+
# allow ecs task execution role to read this app's parameters
165+
resource "aws_iam_policy" "ecsTaskExecutionRole_ssm" {
166+
name = "${var.app}-${var.environment}-ecs-ssm"
167+
path = "/"
168+
description = "allow ecs task execution role to read this app's parameters"
169+
170+
policy = <<EOF
171+
{
172+
"Version": "2012-10-17",
173+
"Statement": [
174+
{
175+
"Effect": "Allow",
176+
"Action": [
177+
"ssm:GetParameters"
178+
],
179+
"Resource": "arn:aws:ssm:${var.region}:${data.aws_caller_identity.current.account_id}:parameter/${var.app}/${var.environment}/*"
180+
}
181+
]
182+
}
183+
EOF
184+
}
185+
186+
resource "aws_iam_role_policy_attachment" "ecsTaskExecutionRole_ssm" {
187+
role = aws_iam_role.ecsTaskExecutionRole.name
188+
policy_arn = aws_iam_policy.ecsTaskExecutionRole_ssm.arn
189+
}
190+
191+
output "ssm_add_secret" {
192+
value = "aws ssm put-parameter --overwrite --type \"SecureString\" --key-id \"${aws_kms_alias.ssm.name}\" --name \"/${var.app}/${var.environment}/PASSWORD\" --value \"password\""
193+
}
194+
195+
output "ssm_add_secret_ref" {
196+
value = "fargate service env set --secret PASSWORD=/${var.app}/${var.environment}/PASSWORD"
197+
}
198+
199+
output "ssm_key_id" {
200+
value = aws_kms_key.ssm.key_id
201+
}

0 commit comments

Comments
 (0)