Skip to content

Commit bc1460e

Browse files
feat: Add support for bundle environments (#34)
- add environment support - restructure scaffolded bundle instances into `/configs` under new structure
2 parents c0e50a9 + b568f4d commit bc1460e

34 files changed

Lines changed: 273 additions & 367 deletions

File tree

README.md

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,6 @@ input "cluster_slug" {
255255
{ name = "${cluster.input.name.value} (${cluster.export.alias.value} / ${cluster.uuid})", value = cluster.export.alias.value }
256256
]
257257
prompt = "Elastic Container Service (ECS) Cluster"
258-
required_for_scaffold = true
259258
}
260259
```
261260

@@ -267,23 +266,43 @@ Both Components and Bundles can be managed and versioned in Git repositories usi
267266

268267
## Project Structure
269268

270-
```
269+
```bash
271270
terramate-catalyst-examples/
271+
272272
├── bundles/ # Bundle definitions
273-
│ └── example.com/
274-
│ ├── tf-aws-s3/v1/
275-
│ ├── tf-aws-complete-ecs-fargate-cluster/v1/
276-
│ └── tf-aws-ecs-fargate-service/v1/
273+
│ └── example.com/ # use your domain here for your own bundles
274+
│ ├── tf-aws-complete-ecs-fargate-cluster/ # The Fargate Cluster bundle
275+
│ ├── tf-aws-ecs-fargate-service/ # The Fargate Workload bundle
276+
│ ├── tf-aws-s3/ # The S3 bundle
277+
│ └── tf-aws-s3/v1/components/terramate-aws-s3-bucket/ # nested component definitions
278+
277279
├── components/ # Component definitions
278-
│ └── example.com/
279-
│ ├── terramate-aws-s3-bucket/v1/
280+
│ └── example.com/ # use your domain here for your own bundles
280281
│ ├── terramate-aws-vpc/v1/
281282
│ ├── terramate-aws-alb/v1/
282283
│ ├── terramate-aws-ecs-cluster/v1/
283284
│ └── terramate-aws-ecs-service/v1/
284-
├── cloud-services/ # Bundle instance files (what developers create)
285-
├── cluster-workloads/ # Bundle instance files for workloads
286-
├── stacks/ # Generated Terramate stacks and Terraform code
285+
286+
# Bundle instances (configured by scaffold and reconfigure commands or manually maintained)
287+
# - each instance contains configurations for all environments in a single file
288+
289+
├── configs/fargate-clusters/{slug}/cluster.tm.yml # Bundle instance files of clusters
290+
├── configs/fargate-clusters/{slug}/service_{name}.tm.yml # Bundle instance files for workloads
291+
├── configs/s3-buckets/s3_{name}.tm.yml # Bundle instance files for s3-buckets
292+
293+
# Generated Terramate Stacks and Terraform Code for all configured environments
294+
295+
# stacks managed by fargate cluster bundles
296+
├── stacks/{env}/fargate-clusters/{cluster}/vpc # a clusters VPC stack
297+
├── stacks/{env}/fargate-clusters/{cluster}/alb # a clusters ALB stack
298+
├── stacks/{env}/fargate-clusters/{cluster}/cluster # the cluster itself stack
299+
300+
# stacks managed by fargate workload bundles
301+
├── stacks/{env}/fargate-clusters/{cluster}/workloads/{service} # workloads for the cluster
302+
303+
# stacks managed by S3 bundles
304+
├── stacks/{env}/s3-buckets/{name} # S3 buckets
305+
287306
└── imports/ # Shared configuration and mixins
288307
```
289308

bundles/example.com/tf-aws-complete-ecs-fargate-cluster/v1/bundle.tm.hcl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@ define bundle metadata {
2424
}
2525

2626
define bundle {
27-
alias = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
27+
alias = tm_slug(bundle.input.name.value)
28+
29+
environments {
30+
required = true
31+
}
2832

2933
scaffolding {
30-
path = "/cloud-services/tf-aws-complete-ecs-fargate-cluster/${tm_slug(bundle.input.name.value)}-${bundle.input.env.value}.tm.hcl"
31-
name = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
34+
path = "/configs/fargate-clusters/${tm_slug(bundle.input.name.value)}/cluster.tm.yml"
35+
name = tm_slug(bundle.input.name.value)
3236
}
3337
}
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
define bundle {
22
export "alias" {
3-
value = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
3+
value = tm_slug(bundle.input.name.value)
44
}
55

66
export "name_slug" {
77
value = tm_slug(bundle.input.name.value)
88
}
99

10-
export "env" {
11-
value = bundle.input.env.value
12-
}
13-
1410
export "alb_name" {
15-
value = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
11+
value = tm_slug(bundle.input.name.value)
1612
}
1713
}

bundles/example.com/tf-aws-complete-ecs-fargate-cluster/v1/inputs.tm.hcl

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
11
define bundle {
2-
input "env" {
3-
type = string
4-
description = "A list of available environments to create the ECS cluster in."
5-
6-
# scaffolding configuration
7-
prompt = "Please chose an environment"
8-
allowed_values = [
9-
for k, v in global.environments : { name = v, value = k }
10-
]
11-
multiselect = false
12-
}
13-
142
input "name" {
153
type = string
164
description = <<-EOF

bundles/example.com/tf-aws-complete-ecs-fargate-cluster/v1/stack_alb.tm.hcl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
define bundle stack "alb" {
22
metadata {
3-
path = "/stacks/${bundle.input.env.value}/ecs-clusters/${tm_slug(bundle.input.name.value)}/alb"
3+
path = "/stacks/${bundle.environment.id}/fargate-clusters/${tm_slug(bundle.input.name.value)}/alb"
44

55
name = "AWS ALB ${bundle.input.name.value}"
66
description = <<-EOF
@@ -11,10 +11,10 @@ define bundle stack "alb" {
1111
bundle.class,
1212
"${bundle.class}/alb",
1313
# "${bundle.class}/ecs-cluster/${bundle.alias}",
14-
"${bundle.class}/ecs-cluster/${tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])}",
14+
"${bundle.class}/ecs-cluster/${tm_join("-", [tm_slug(bundle.input.name.value), bundle.environment.id])}",
1515

1616
# tag the environment
17-
"environment/${bundle.input.env.value}",
17+
"environment/${bundle.environment.id}",
1818

1919
# configure aws and null provider for this stack
2020
"terraform/provider/aws",
@@ -30,7 +30,7 @@ define bundle stack "alb" {
3030
source = "/components/example.com/terramate-aws-alb/v1"
3131
inputs = {
3232
# name = bundle.alias
33-
name = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
33+
name = tm_join("-", [tm_slug(bundle.input.name.value), bundle.environment.id])
3434

3535
# The component will automatically find the VPC and subnets by bundle UUID tag
3636
vpc_filter_tags = {
@@ -84,7 +84,8 @@ define bundle stack "alb" {
8484
tags = {
8585
"${bundle.class}/bundle-uuid" = bundle.uuid
8686
# "${bundle.class}/bundle-alias" = bundle.alias
87-
"${bundle.class}/bundle-alias" = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
87+
"${bundle.class}/bundle-alias" = tm_slug(bundle.input.name.value)
88+
"${bundle.class}/environment" = bundle.environment.id
8889
}
8990
}
9091
}

bundles/example.com/tf-aws-complete-ecs-fargate-cluster/v1/stack_ecs_cluster.tm.hcl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
define bundle stack "ecs-cluster" {
22
metadata {
3-
path = "/stacks/${bundle.input.env.value}/ecs-clusters/${tm_slug(bundle.input.name.value)}/cluster"
3+
path = "/stacks/${bundle.environment.id}/fargate-clusters/${tm_slug(bundle.input.name.value)}/cluster"
44

55
name = "AWS ECS Fargate Cluster ${bundle.input.name.value}"
66
description = <<-EOF
@@ -11,10 +11,10 @@ define bundle stack "ecs-cluster" {
1111
bundle.class,
1212
"${bundle.class}/ecs-cluster",
1313
# "${bundle.class}/ecs-cluster/${bundle.alias}",
14-
"${bundle.class}/ecs-cluster/${tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])}",
14+
"${bundle.class}/ecs-cluster/${tm_join("-", [tm_slug(bundle.input.name.value), bundle.environment.id])}",
1515

1616
# tag the environment
17-
"environment/${bundle.input.env.value}",
17+
"environment/${bundle.environment.id}",
1818

1919
# configure aws and null provider for this stack
2020
"terraform/provider/aws",
@@ -27,12 +27,13 @@ define bundle stack "ecs-cluster" {
2727

2828
inputs = {
2929
# cluster_name = bundle.alias
30-
cluster_name = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
30+
cluster_name = tm_join("-", [tm_slug(bundle.input.name.value), bundle.environment.id])
3131
bundle_uuid = bundle.uuid
3232
tags = {
3333
"${bundle.class}/bundle-uuid" = bundle.uuid
3434
# "${bundle.class}/bundle-alias" = bundle.alias
35-
"${bundle.class}/bundle-alias" = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
35+
"${bundle.class}/bundle-alias" = tm_slug(bundle.input.name.value)
36+
"${bundle.class}/environment" = bundle.environment.id
3637
}
3738
}
3839
}

bundles/example.com/tf-aws-complete-ecs-fargate-cluster/v1/stack_vpc.tm.hcl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
define bundle stack "vpc" {
22
metadata {
3-
path = "/stacks/${bundle.input.env.value}/ecs-clusters/${tm_slug(bundle.input.name.value)}/vpc"
3+
path = "/stacks/${bundle.environment.id}/fargate-clusters/${tm_slug(bundle.input.name.value)}/vpc"
44

55
name = "AWS VPC ${bundle.input.name.value}"
66
description = <<-EOF
@@ -11,10 +11,10 @@ define bundle stack "vpc" {
1111
bundle.class,
1212
"${bundle.class}/vpc",
1313
# "${bundle.class}/ecs-cluster/${bundle.alias}",
14-
"${bundle.class}/ecs-cluster/${tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])}",
14+
"${bundle.class}/ecs-cluster/${tm_slug(bundle.input.name.value)}",
1515

1616
# tag the environment
17-
"environment/${bundle.input.env.value}",
17+
"environment/${bundle.environment.id}",
1818

1919
# configure aws and null provider for this stack
2020
"terraform/provider/aws",
@@ -26,12 +26,13 @@ define bundle stack "vpc" {
2626
source = "/components/example.com/terramate-aws-vpc/v1"
2727
inputs = {
2828
# name = bundle.alias
29-
name = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
29+
name = tm_join("-", [tm_slug(bundle.input.name.value), bundle.environment.id])
3030
cidr = bundle.input.vpc_cidr.value
3131
tags = {
3232
"${bundle.class}/bundle-uuid" = bundle.uuid
33-
# "${bundle.class}/bundle-alias" = bundle.alias
34-
"${bundle.class}/bundle-alias" = tm_join("-", [tm_slug(bundle.input.name.value), bundle.input.env.value])
33+
# "${bundle.class}/bundle-alias" = bundle.alias
34+
"${bundle.class}/bundle-alias" = tm_slug(bundle.input.name.value)
35+
"${bundle.class}/environment" = bundle.environment.id
3536
}
3637
}
3738
}

bundles/example.com/tf-aws-ecs-fargate-service/v1/bundle.tm.hcl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,21 @@ define bundle metadata {
1313
define bundle {
1414
alias = tm_join("-", [bundle.input.cluster_slug.value, tm_slug(bundle.input.service_name.value)])
1515

16+
environments {
17+
required = true
18+
}
19+
1620
scaffolding {
17-
path = "/cluster-workloads/${bundle.input.cluster_slug.value}/${tm_slug(bundle.input.service_name.value)}.tm.hcl"
21+
path = "/configs/fargate-clusters/${bundle.input.cluster_slug.value}/service_${tm_slug(bundle.input.service_name.value)}.tm.yml"
1822

1923
name = tm_slug(bundle.input.service_name.value)
2024

2125
enabled {
2226
condition = tm_length(tm_bundles("example.com/tf-aws-complete-ecs-fargate-cluster/v1")) > 0
2327
error_message = <<-EOF
2428
This bundle requires an instance of the AWS ECS Fargate Cluster (example.com/tf-aws-complete-ecs-fargate-cluster/v1) bundle.
29+
30+
There seems to be no bundle instance in the selected environment: ${bundle.environment.name} [${bundle.environment.id}]
2531
EOF
2632
}
2733
}

bundles/example.com/tf-aws-ecs-fargate-service/v1/inputs.tm.hcl

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,11 @@ define bundle {
1212
# scaffolding configuration
1313
allowed_values = [
1414
for cluster in tm_bundles("example.com/tf-aws-complete-ecs-fargate-cluster/v1") :
15-
{ name = "${cluster.input.name.value} (${cluster.export.alias.value} / ${cluster.uuid})", value = cluster.export.alias.value }
15+
{ name = "${cluster.input.name.value} (${cluster.export.alias.value} / ${cluster.uuid}) [${cluster.environment.id}]", value = cluster.export.alias.value }
1616
]
1717
prompt = "Elastic Container Service (ECS) Cluster"
1818
}
1919

20-
# input "cluster_bundle_uuid" {
21-
# type = string
22-
# description = "Bundle UUID of the ECS cluster to attach this service to"
23-
# required_for_scaffold = true
24-
# allowed_values = [for cluster in tm_bundles("example.com/tf-aws-ecs-fargate-cluster/v1") :
25-
# { name = "${cluster.input.cluster_name.value} (${cluster.uuid})", value = cluster.uuid }
26-
# ]
27-
# prompt = "Elastic Container Service (ECS) Cluster"
28-
# }
29-
30-
# input "alb_bundle_uuid" {
31-
# type = string
32-
# description = "The ALB to attach this service to"
33-
# required_for_scaffold = true
34-
# allowed_values = tm_concat(
35-
# [for alb in tm_bundles("example.com/tf-aws-vpc-alb/v1") :
36-
# { name = "${alb.input.name.value} (${alb.uuid})", value = alb.uuid }
37-
# ]
38-
# )
39-
# prompt = "Application Load Balancer (ALB)"
40-
# }
41-
4220
input "container_name" {
4321
type = string
4422
prompt = "Container Name"

bundles/example.com/tf-aws-ecs-fargate-service/v1/stack_ecs-service.tm.hcl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
define bundle stack "ecs-service" {
22
metadata {
3-
path = "/stacks/${tm_regex("-([^-]+)$", bundle.input.cluster_slug.value)[0]}/ecs-clusters/${tm_regex("^(.*)-[^-]+$", bundle.input.cluster_slug.value)[0]}/workloads/${tm_slug(bundle.input.service_name.value)}"
3+
path = "/stacks/${bundle.environment.id}/fargate-clusters/${bundle.input.cluster_slug.value}/workloads/${tm_slug(bundle.input.service_name.value)}"
44

55
name = "AWS ECS Fargate Service ${bundle.input.service_name.value}"
66
description = <<-EOF
@@ -9,7 +9,7 @@ define bundle stack "ecs-service" {
99

1010
tags = [
1111
bundle.class,
12-
"${bundle.class}/ecs-service",
12+
"environemnt/${bundle.environment.id}",
1313
]
1414

1515
after = [
@@ -30,14 +30,14 @@ define bundle stack "ecs-service" {
3030

3131
# VPC is derived from the ALB bundle (they share the same UUID in the VPC-ALB bundle)
3232
vpc_filter_tags = {
33-
"example.com/tf-aws-complete-ecs-fargate-cluster/v1/bundle-uuid" = tm_bundle("example.com/tf-aws-complete-ecs-fargate-cluster/v1", bundle.input.cluster_slug.value).uuid
33+
"example.com/tf-aws-complete-ecs-fargate-cluster/v1/bundle-uuid" = tm_bundle("example.com/tf-aws-complete-ecs-fargate-cluster/v1", bundle.input.cluster_slug.value, bundle.environment.id).uuid
3434
}
3535

3636
alb_filter_tags = {
37-
"example.com/tf-aws-complete-ecs-fargate-cluster/v1/bundle-uuid" = tm_bundle("example.com/tf-aws-complete-ecs-fargate-cluster/v1", bundle.input.cluster_slug.value).uuid
37+
"example.com/tf-aws-complete-ecs-fargate-cluster/v1/bundle-uuid" = tm_bundle("example.com/tf-aws-complete-ecs-fargate-cluster/v1", bundle.input.cluster_slug.value, bundle.environment.id).uuid
3838
}
3939

40-
alb_name = tm_bundle("example.com/tf-aws-complete-ecs-fargate-cluster/v1", bundle.input.cluster_slug.value).export.alb_name.value
40+
alb_name = tm_bundle("example.com/tf-aws-complete-ecs-fargate-cluster/v1", bundle.input.cluster_slug.value, bundle.environment.id).export.alb_name.value
4141
target_group_name = tm_substr(tm_join("-", [bundle.input.cluster_slug.value, tm_slug(bundle.input.service_name.value)]), 0, 32)
4242

4343
target_group_key = bundle.input.target_group_key.value
@@ -80,6 +80,7 @@ define bundle stack "ecs-service" {
8080
"${bundle.class}/bundle-uuid" = bundle.uuid
8181
# "${bundle.class}/bundle-alias" = bundle.alias
8282
"${bundle.class}/bundle-alias" = tm_join("-", [bundle.input.cluster_slug.value, tm_slug(bundle.input.service_name.value)])
83+
"${bundle.class}/environment" = bundle.environment.id
8384
}
8485
}
8586
}

0 commit comments

Comments
 (0)