Skip to content

Commit 7239283

Browse files
authored
feat: update doc and ecs service optimize (#36)
* (add): cloudwatch loffroup name * (update): log_group name * feat: add output * feat: change to 1 sercret manager for cost saving * fix: typo * fix: typo * chore: remove ocmment * chore: update example usage * chore: uncomment outputs * chore: uncomment outputs * chore: remove previous secret * chore: revert * chore: test l=5 on random_string * chore: add output backs * chore: update document and changelog * feat: tag propagate (#37) * chore: update CHANGLOG
1 parent 5bb288e commit 7239283

File tree

10 files changed

+233
-223
lines changed

10 files changed

+233
-223
lines changed

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
# Change Log
22

3+
## [v1.1.12] - 2023-01-23
4+
5+
### Added
6+
7+
- Add and verify example in `./examples/simple`
8+
- Add outputs `cloudwatch_log_group_name` and `cloudwatch_log_group_arn`
9+
- Add variable `propagate_tags` with default value TASK_DEFINITION
10+
11+
### Changed
12+
13+
- Target group naming `local.log_group_name`; remove `service` in string
14+
- Update task definition's construction procedure for the secret ARN
15+
- Update resource `random_string.service_secret_random_suffix`'s attribute `length` from 6 to 5
16+
- Update resource `aws_iam_role_policy.task_execution_secrets`'s condition and resource arns
17+
- Update resource `aws_ecs_service.this` to support propagate_tags
18+
19+
### Removed
20+
21+
- Remove `local.task_role_id`
22+
- Remove all previous secrets creation
23+
- The following `local` are removed `secret_manager_arns` ,`secret_names`, `secrets_name_arn_map`, `secrets_task_unique_definition`, `secret_manager_json_arn`, `secrets_name_json_arn_map`, `secrets_json_task_definition`
24+
- Remove resource:
25+
- `aws_secretsmanager_secret.service_json_secrets`
26+
- `aws_secretsmanager_secret_version.service_json_secrets`
27+
- Remove outputs `outask_role_id` and `secret_json_arn`
28+
- Remove variable `json_secret_variables`
29+
330
## [v1.1.11] - 2022-12-22
431

532
### Added

README.md

Lines changed: 88 additions & 91 deletions
Large diffs are not rendered by default.

examples/simple/README.md

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,26 +65,33 @@ No requirements.
6565

6666
## Providers
6767

68-
No providers.
68+
| Name | Version |
69+
|---------------------------------------------------|---------|
70+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 4.50.0 |
6971

7072
## Modules
7173

72-
| Name | Source | Version |
73-
|------|--------|---------|
74-
| <a name="module_service_api"></a> [service\_api](#module\_service\_api) | ../.. | n/a |
74+
| Name | Source | Version |
75+
|-------------------------------------------------------------------------------------|-------------------------------|---------|
76+
| <a name="module_fargate_cluster"></a> [fargate\_cluster](#module\_fargate\_cluster) | oozou/ecs-fargate-cluster/aws | 1.0.7 |
77+
| <a name="module_service_api"></a> [service\_api](#module\_service\_api) | ../.. | n/a |
78+
| <a name="module_vpc"></a> [vpc](#module\_vpc) | oozou/vpc/aws | 1.2.4 |
7579

7680
## Resources
7781

78-
No resources.
82+
| Name | Type |
83+
|----------------------------------------------------------------------------------------------------------------------------|-------------|
84+
| [aws_caller_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
85+
| [aws_region.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
7986

8087
## Inputs
8188

82-
| Name | Description | Type | Default | Required |
83-
|------|-------------|------|---------|:--------:|
84-
| <a name="input_generics_info"></a> [generics\_info](#input\_generics\_info) | Generic infomation | <pre>object({<br> region = string<br> prefix = string<br> environment = string<br> name = string<br> custom_tags = map(any)<br> })</pre> | n/a | yes |
85-
| <a name="input_service_info"></a> [service\_info](#input\_service\_info) | is\_attach\_service\_with\_lb >> Attach the container to the public ALB? (true/false)<br> service\_alb\_host\_header >> Mention host header for api endpoint<br> service\_info >> The configuration of service<br> health\_check >> Health Check Config for the service | <pre>map(object({<br> is_attach_service_with_lb = bool<br> service_alb_host_header = string<br> alb_paths = list(string)<br> alb_priority = string<br> service_info = object({<br> cpu_allocation = number<br> mem_allocation = number<br> containers_num = number<br> port = number<br> image = string<br> })<br> health_check = object({<br> interval = number<br> path = string<br> timeout = number<br> healthy_threshold = number<br> unhealthy_threshold = number<br> matcher = string<br> })<br> }))</pre> | n/a | yes |
86-
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | A list of subnet IDs to launch resources in | `list(string)` | n/a | yes |
87-
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | VPC ID to deploy | `string` | n/a | yes |
89+
| Name | Description | Type | Default | Required |
90+
|-----------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|---------------|---------|:--------:|
91+
| <a name="input_custom_tags"></a> [custom\_tags](#input\_custom\_tags) | Custom tags which can be passed on to the AWS resources. They should be key value pairs having distinct keys. | `map(string)` | `{}` | no |
92+
| <a name="input_environment"></a> [environment](#input\_environment) | [Required] Name prefix used for resource naming in this component | `string` | n/a | yes |
93+
| <a name="input_name"></a> [name](#input\_name) | [Required] Name of Platfrom or application | `string` | n/a | yes |
94+
| <a name="input_prefix"></a> [prefix](#input\_prefix) | [Required] Name prefix used for resource naming in this component | `string` | n/a | yes |
8895

8996
## Outputs
9097

examples/simple/main.tf

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,39 @@
1-
# Please see how to use fargate cluster at ooozou/terraform-aws-fargate-cluster
1+
data "aws_caller_identity" "this" {}
2+
data "aws_region" "this" {}
3+
4+
/* -------------------------------------------------------------------------- */
5+
/* VPC */
6+
/* -------------------------------------------------------------------------- */
7+
module "vpc" {
8+
source = "oozou/vpc/aws"
9+
version = "1.2.4"
10+
11+
prefix = var.prefix
12+
environment = var.environment
13+
account_mode = "spoke"
14+
15+
cidr = "172.17.170.128/25"
16+
public_subnets = ["172.17.170.192/28", "172.17.170.208/28"]
17+
private_subnets = ["172.17.170.224/28", "172.17.170.240/28"]
18+
database_subnets = ["172.17.170.128/27", "172.17.170.160/27"]
19+
availability_zone = ["ap-southeast-1b", "ap-southeast-1c"]
20+
21+
is_create_nat_gateway = true
22+
is_enable_single_nat_gateway = true
23+
is_enable_dns_hostnames = true
24+
is_enable_dns_support = true
25+
is_create_flow_log = false
26+
is_enable_flow_log_s3_integration = false
227

3-
module "fargate_cluster" {
28+
tags = var.custom_tags
29+
}
430

5-
source = "git@github.com:oozou/terraform-aws-ecs-fargate-cluster?ref=v1.0.6"
31+
/* -------------------------------------------------------------------------- */
32+
/* Fargate Cluster */
33+
/* -------------------------------------------------------------------------- */
34+
module "fargate_cluster" {
35+
source = "oozou/ecs-fargate-cluster/aws"
36+
version = "1.0.7"
637

738
# Generics
839
prefix = var.prefix
@@ -12,7 +43,7 @@ module "fargate_cluster" {
1243
# IAM Role
1344
## If is_create_role is false, all of folowing argument is ignored
1445
is_create_role = true
15-
allow_access_from_principals = ["arn:aws:iam::557291035693:root"]
46+
allow_access_from_principals = ["arn:aws:iam::${data.aws_caller_identity.this.account_id}:root"]
1647
additional_managed_policy_arns = []
1748

1849
# VPC Information
@@ -21,10 +52,11 @@ module "fargate_cluster" {
2152
additional_security_group_ingress_rules = {}
2253

2354
# ALB
24-
is_create_alb = true
25-
is_public_alb = true
26-
enable_deletion_protection = false
27-
alb_listener_port = 8080
55+
is_create_alb = true
56+
is_public_alb = true
57+
enable_deletion_protection = false
58+
alb_listener_port = 80
59+
is_ignore_unsecured_connection = true
2860
# alb_certificate_arn = var.alb_certificate_arn
2961
public_subnet_ids = module.vpc.public_subnet_ids # If is_public_alb is true, public_subnet_ids is required
3062

@@ -34,6 +66,9 @@ module "fargate_cluster" {
3466
tags = var.custom_tags
3567
}
3668

69+
/* -------------------------------------------------------------------------- */
70+
/* Service */
71+
/* -------------------------------------------------------------------------- */
3772
module "service_api" {
3873
source = "../.."
3974

@@ -49,7 +84,7 @@ module "service_api" {
4984
]
5085

5186
# ALB
52-
is_attach_service_with_lb = false
87+
is_attach_service_with_lb = true
5388
alb_listener_arn = module.fargate_cluster.alb_listener_http_arn
5489
alb_host_header = null
5590
alb_paths = ["/*"]
@@ -69,7 +104,6 @@ module "service_api" {
69104

70105
# Task definition
71106
service_info = {
72-
containers_num = 2,
73107
cpu_allocation = 256,
74108
mem_allocation = 512,
75109
port = 80,
@@ -78,6 +112,21 @@ module "service_api" {
78112
}
79113
is_application_scratch_volume_enabled = true
80114

115+
# Secret and Env
116+
environment_variables = {
117+
THIS_IS_ENV = "ENV1",
118+
THIS_IS_ENVV = "ENVV",
119+
}
120+
# WARNING Secret should not be in plain text
121+
secret_variables = {
122+
THIS_IS_SECRET = "1xxxxx",
123+
THIS_IS_SECRETT = "2xxxxx",
124+
THIS_IS_SECRETTT = "3xxxxx",
125+
THIS_IS_SECRETTTTT = "4xxxxx",
126+
THIS_IS_SECRETTTTTT = "5xxxxx",
127+
THIS_IS_SECRETTTTTTT = "6xxxxx",
128+
}
129+
81130
# ECS service
82131
ecs_cluster_name = module.fargate_cluster.ecs_cluster_name
83132
service_discovery_namespace = module.fargate_cluster.service_discovery_namespace

examples/simple/terraform.auto.tfvars

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
prefix = "oozou"
2+
environment = "devops"
3+
name = "demo"
4+
custom_tags = {
5+
"Remark" = "terraform-aws-ecs-service"
6+
}

examples/simple/vpc.tf

Lines changed: 0 additions & 16 deletions
This file was deleted.

locals.tf

Lines changed: 7 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ locals {
1010
# Task Role
1111
task_role_arn = var.is_create_iam_role ? aws_iam_role.task_role[0].arn : var.exists_task_role_arn
1212
task_role_name = try(split("/", local.task_role_arn)[1], "")
13-
task_role_id = local.task_role_name
1413

1514
# Task Exec Role
1615
task_execution_role_arn = var.is_create_iam_role ? aws_iam_role.task_execution_role[0].arn : var.exists_task_execution_role_arn
@@ -20,7 +19,7 @@ locals {
2019
ecs_task_execution_role_policy_arns = toset(concat(var.additional_ecs_task_execution_role_policy_arns, local.ecs_default_task_execution_role_policy_arns))
2120

2221
# Logging
23-
log_group_name = format("%s-service-log-group", local.name)
22+
log_group_name = format("%s-log-group", local.name)
2423

2524
# Volume
2625
volumes = concat(var.efs_volumes)
@@ -85,7 +84,7 @@ locals {
8584
name = local.name
8685
service_port = var.service_info.port
8786
environment_variables = jsonencode(local.environment_variables)
88-
secret_variables = jsonencode(local.secrets_task_unique_definition)
87+
secret_variables = jsonencode(local.secrets_task_definition)
8988
entry_point = jsonencode(var.entry_point)
9089
mount_points = jsonencode(local.mount_points)
9190
command = jsonencode(var.command)
@@ -108,46 +107,13 @@ locals {
108107
}
109108

110109
/* -------------------------------------------------------------------------- */
111-
/* SECRET */
110+
/* Secret */
112111
/* -------------------------------------------------------------------------- */
113112
locals {
114-
# Create secret arn collection for granting "secretmanager:GetSecret" permission
115-
secret_manager_arns = [for secret in aws_secretsmanager_secret.service_secrets : secret.arn]
116-
117-
# Get Secret Name Arrays
118-
secret_names = keys(var.secret_variables)
119-
120-
# Create a secret map { secret_name : secret_arn } using ZipMap Function for iteration
121-
secrets_name_arn_map = zipmap(local.secret_names, local.secret_manager_arns)
122-
123-
# Create secrets format for Task Definition
124-
secrets_task_unique_definition = [for secret_key, secret_arn in local.secrets_name_arn_map :
125-
tomap({
126-
name = upper(secret_key)
127-
valueFrom = secret_arn
128-
})
129-
]
130-
}
131-
132-
/* -------------------------------------------------------------------------- */
133-
/* JSON SECRET */
134-
/* -------------------------------------------------------------------------- */
135-
locals {
136-
# Get secret arn for granting "secretmanager:GetSecret" permission
137-
secret_manager_json_arn = aws_secretsmanager_secret.service_json_secrets.arn
138-
139-
# Map JSON Secret to Secret Arrays
140-
secrets_name_json_arn_map = { "JSON_SECRET" : local.secret_manager_json_arn }
141-
142-
# Create secrets JSON format for Task Definition
143-
secrets_json_task_definition = [for secret_key, secret_arn in local.secrets_name_json_arn_map :
144-
tomap({
145-
name = upper(secret_key)
146-
valueFrom = secret_arn
147-
})
148-
]
149-
# Concat Secret and JSON Secret to the one list.
150-
secrets_task_definition = concat(local.secrets_task_unique_definition, local.secrets_json_task_definition)
113+
secrets_task_definition = [for secret_name, secret_value in var.secret_variables : {
114+
name = secret_name,
115+
valueFrom = format("%s:%s::", aws_secretsmanager_secret_version.service_secrets.arn, secret_name)
116+
}]
151117
}
152118

153119
/* -------------------------------------------------------------------------- */

main.tf

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -166,58 +166,31 @@ module "secret_kms_key" {
166166
tags = merge(local.tags, { "Name" : format("%s-ecs", local.name) })
167167
}
168168

169-
# Append random string to SM Secret names because once we tear down the infra, the secret does not actually
170-
# get deleted right away, which means that if we then try to recreate the infra, it'll fail as the
171-
# secret name already exists.
172169
resource "random_string" "service_secret_random_suffix" {
173-
length = 6
170+
length = 5
174171
special = false
175172
}
176173

174+
/* -------------------------------------------------------------------------- */
175+
/* Secret */
176+
/* -------------------------------------------------------------------------- */
177177
resource "aws_secretsmanager_secret" "service_secrets" {
178-
for_each = var.secret_variables
179-
180-
name = "${local.name}/${lower(each.key)}-${random_string.service_secret_random_suffix.result}"
181-
description = "Secret 'secret_${lower(each.key)}' for service ${local.name}"
182-
kms_key_id = module.secret_kms_key.key_arn
183-
184-
tags = merge(local.tags, { Name = "${local.name}/${each.key}" })
185-
}
186-
187-
resource "aws_secretsmanager_secret_version" "service_secrets" {
188-
for_each = var.secret_variables
189-
190-
secret_id = aws_secretsmanager_secret.service_secrets[each.key].id
191-
secret_string = each.value
192-
}
193-
194-
195-
# /* -------------------------------------------------------------------------- */
196-
# /* JSON SECRET */
197-
# /* -------------------------------------------------------------------------- */
198-
resource "aws_secretsmanager_secret" "service_json_secrets" {
199178
name = "${local.name}/${random_string.service_secret_random_suffix.result}"
200179
description = "Secret for service ${local.name}"
201180
kms_key_id = module.secret_kms_key.key_arn
202181

203-
tags = merge({
204-
Name = "${local.name}"
205-
}, local.tags)
206-
207-
provider = aws
182+
tags = merge({ Name = "${local.name}" }, local.tags)
208183
}
209184

210-
resource "aws_secretsmanager_secret_version" "service_json_secrets" {
211-
secret_id = aws_secretsmanager_secret.service_json_secrets.id
212-
secret_string = jsonencode(var.json_secret_variables)
213-
214-
provider = aws
185+
resource "aws_secretsmanager_secret_version" "service_secrets" {
186+
secret_id = aws_secretsmanager_secret.service_secrets.id
187+
secret_string = jsonencode(var.secret_variables)
215188
}
216189

217190
# We add a policy to the ECS Task Execution role so that ECS can pull secrets from SecretsManager and
218191
# inject them as environment variables in the service
219192
resource "aws_iam_role_policy" "task_execution_secrets" {
220-
count = var.is_create_iam_role ? 1 : 0
193+
count = var.is_create_iam_role && length(var.secret_variables) > 0 ? 1 : 0
221194

222195
name = "${local.name}-ecs-task-execution-secrets"
223196
role = local.task_execution_role_id
@@ -228,7 +201,7 @@ resource "aws_iam_role_policy" "task_execution_secrets" {
228201
{
229202
"Effect": "Allow",
230203
"Action": ["secretsmanager:GetSecretValue"],
231-
"Resource": ${jsonencode(format("%s/*", split("/", local.secret_manager_json_arn)[0]))}
204+
"Resource": ${jsonencode(format("%s/*", split("/", aws_secretsmanager_secret.service_secrets.arn)[0]))}
232205
}
233206
]
234207
}
@@ -314,6 +287,7 @@ resource "aws_ecs_service" "this" {
314287
enable_execute_command = var.is_enable_execute_command
315288
enable_ecs_managed_tags = true
316289
launch_type = var.capacity_provider_strategy == null ? "FARGATE" : null
290+
propagate_tags = var.propagate_tags
317291

318292
network_configuration {
319293
security_groups = var.security_groups

0 commit comments

Comments
 (0)