Skip to content

Commit 60ad05e

Browse files
author
rahul-infra
committed
feat!: updated providers in acm module.
formatted terraform file. terraform-docs: automated action Updated examples for same account and cross account. Added line enter. Updated readme for same account and cross account examplefile. terraform-docs: automated action updated root readme file.
1 parent 8d911e9 commit 60ad05e

File tree

18 files changed

+664
-33
lines changed

18 files changed

+664
-33
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
# terraform-aws-ecs-deployment
33

44
Terraform module to deploy production-ready applications and services on an existing ECS infra.
5+
This module supports both same-account and cross-account ACM → Route53 validation workflows. For same-account usage, simply map the providers as providers = { aws = aws, aws.cross_account_provider = aws } without any assume role.
6+
For cross-account setups, you must create an IAM Role in the Route53 Hosted Zone account (Account B) that allows Account A (where ACM and application resources are created) to assume it. This role should grant permissions such as route53:ChangeResourceRecordSets, route53:ListHostedZonesByName, and route53:ListResourceRecordSets, along with a trust policy that permits Account A to assume the role.
7+
When using cross-account mode, configure an alias provider with assume_role and pass it to the module as:
8+
providers = { aws = aws, aws.cross_account_provider = aws.cross_account_provider }.
59

610
## Architecture Diagram
711

@@ -51,7 +55,6 @@ Terraform module to deploy production-ready applications and services on an exis
5155
| <a name="input_create_s3_bucket_for_alb_logging"></a> [create\_s3\_bucket\_for\_alb\_logging](#input\_create\_s3\_bucket\_for\_alb\_logging) | (Optional) Creates S3 bucket for storing ALB Access and Connection Logs. | `bool` | `true` | no |
5256
| <a name="input_default_capacity_providers_strategies"></a> [default\_capacity\_providers\_strategies](#input\_default\_capacity\_providers\_strategies) | (Optional) Set of capacity provider strategies to use by default for the cluster. | `any` | `[]` | no |
5357
| <a name="input_load_balancer"></a> [load\_balancer](#input\_load\_balancer) | Configuration for the Application Load Balancer. | <pre>object({<br/> name = optional(string)<br/> internal = optional(bool, false)<br/> subnets_ids = optional(list(string), [])<br/> security_groups_ids = optional(list(string), [])<br/> preserve_host_header = optional(bool)<br/> enable_deletion_protection = optional(bool, false)<br/> access_logs = optional(any, null)<br/> connection_logs = optional(any, null)<br/> target_groups = optional(any, {})<br/> listeners = optional(any, {})<br/> listener_rules = optional(any, {})<br/> tags = optional(map(string), {})<br/> })</pre> | `{}` | no |
54-
| <a name="input_region"></a> [region](#input\_region) | (Optional) AWS region to create resources in. | `string` | `null` | no |
5558
| <a name="input_route53_assume_role_arn"></a> [route53\_assume\_role\_arn](#input\_route53\_assume\_role\_arn) | (Optional) ARN of the role to assume for Route53 operations. | `string` | `null` | no |
5659
| <a name="input_s3_bucket_force_destroy"></a> [s3\_bucket\_force\_destroy](#input\_s3\_bucket\_force\_destroy) | (Optional, Default:false) Boolean that indicates all objects (including any locked objects) should be deleted from the bucket when the bucket is destroyed so that the bucket can be destroyed without error. | `bool` | `false` | no |
5760
| <a name="input_s3_bucket_name"></a> [s3\_bucket\_name](#input\_s3\_bucket\_name) | (Optional, Forces new resource) Name of the bucket. | `string` | `null` | no |

examples/cross-account/.header.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# ECS Deployment Complete
2+
3+
Configuration in this directory creates:
4+
5+
- ECS Service in a pre-configured ECS Cluster and corresponding ECS Capacity Providers
6+
- Internet-facing Application Load Balancer to access the deployed services with S3 bucket for storing access and connection logs, and
7+
- ACM to generate and validate an Amazon-issued certificate for a base domain
8+
9+
## Example `tfvars` Configuration
10+
11+
```tf
12+
vpc_id = "vpc-0123456789abcdefg"
13+
service_network_configuration_security_groups = ["sg-0123456789abcdefg"]
14+
private_subnets = ["subnet-0123456789abcdefg", "subnet-0123456789abcdefg"]
15+
public_subnets = ["subnet-0123456789abcdefg", "subnet-0123456789abcdefg"]
16+
cluster_name = "your-cluster-name"
17+
container_name = "your-container-name"
18+
service_desired_count = 123
19+
container_image = "your-container-image:version"
20+
container_port = 123
21+
container_cpu = 123
22+
container_memory = 123
23+
container_essential = true
24+
container_port_mappings = [
25+
{
26+
name = "your-port-mapping-name"
27+
containerPort = 123
28+
hostPort = 123
29+
protocol = "your-port-mapping-protocol"
30+
}
31+
]
32+
container_readonly_root_filesystem = false
33+
asg_arn = "arn:aws:autoscaling:your-region:01234567890:autoScalingGroup:abcdefgh-ijkl-mnop-qrst-uvwxyz012345:autoScalingGroupName/your-autoscaling-group-name"
34+
capacity_provider_name = "your-capacity-provider-name"
35+
capacity_provider_managed_scaling = {
36+
status = "ENABLED"
37+
target_capacity = 123
38+
minimum_scaling_step_size = 123
39+
maximum_scaling_step_size = 123
40+
}
41+
alb_name = "your-alb-name"
42+
target_group_name = "your-alb-target-group-name"
43+
target_group_protocol = "HTTP"
44+
target_group_health_check = {
45+
path = "/path/to/health/check"
46+
}
47+
listener_port = 123
48+
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
49+
security_group_alb = "your-alb-sg-name"
50+
s3_bucket_force_destroy = true
51+
base_domain = "example.com"
52+
domain_name = "your-service.example.com"
53+
region = "us-east-1"
54+
route53_assume_role_arn = "arn:aws:iam::123456789012:role/Route53CrossAccountRole"
55+
```
56+
57+
## Usage
58+
59+
To run this example, you will need to execute the commands:
60+
61+
```bash
62+
terraform init
63+
terraform plan
64+
terraform apply
65+
```
66+
67+
Please note that this example may create resources that can incur monetary charges on your AWS bill. You can run `terraform destroy` when you no longer need the resources.

examples/cross-account/README.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
<!-- BEGIN_TF_DOCS -->
2+
# ECS Deployment Complete
3+
4+
5+
6+
Configuration in this directory creates:
7+
8+
- ECS Service in a pre-configured ECS Cluster and corresponding ECS Capacity Providers
9+
- Internet-facing Application Load Balancer to access the deployed services with S3 bucket for storing access and connection logs, and
10+
- ACM to generate and validate an Amazon-issued certificate for a base domain
11+
12+
13+
For cross-account Route53 validation, configure the alias provider with assume_role and pass it to the module as:
14+
providers = { aws = aws, aws.cross_account_provider = aws.cross_account_provider }.
15+
Ensure the cross_account_provider includes the assume_role block pointing to the Route53 account role.
16+
provider "aws" { alias = "cross_account_provider" ... assume_role { role_arn = "<role>" } }
17+
18+
## Prerequisites
19+
20+
**Create an IAM Role in the Hosted Zone Account (Account B)**
21+
If you want to validate ACM certificates across accounts, ensure that an IAM role exists in Account B (Route53 Hosted Zone account) that grants cross-account access to manage Route53 DNS records.
22+
This role must allow Account A (where ACM and your application resources are created) to assume it.
23+
It should include permissions such as:
24+
25+
route53:ChangeResourceRecordSets
26+
route53:ListHostedZonesByName
27+
route53:ListResourceRecordSets
28+
29+
And a trust policy allowing Account A to assume the role.
30+
31+
32+
## Example `tfvars` Configuration
33+
34+
```tf
35+
vpc_id = "vpc-0123456789abcdefg"
36+
service_network_configuration_security_groups = ["sg-0123456789abcdefg"]
37+
private_subnets = ["subnet-0123456789abcdefg", "subnet-0123456789abcdefg"]
38+
public_subnets = ["subnet-0123456789abcdefg", "subnet-0123456789abcdefg"]
39+
40+
cluster_name = "your-cluster-name"
41+
container_name = "your-container-name"
42+
service_desired_count = 123
43+
container_image = "your-container-image:version"
44+
container_port = 123
45+
container_cpu = 123
46+
container_memory = 123
47+
container_essential = true
48+
container_port_mappings = [
49+
{
50+
name = "your-port-mapping-name"
51+
containerPort = 123
52+
hostPort = 123
53+
protocol = "your-port-mapping-protocol"
54+
}
55+
]
56+
container_readonly_root_filesystem = false
57+
58+
asg_arn = "arn:aws:autoscaling:your-region:01234567890:autoScalingGroup:abcdefgh-ijkl-mnop-qrst-uvwxyz012345:autoScalingGroupName/your-autoscaling-group-name"
59+
capacity_provider_name = "your-capacity-provider-name"
60+
capacity_provider_managed_scaling = {
61+
status = "ENABLED"
62+
target_capacity = 123
63+
minimum_scaling_step_size = 123
64+
maximum_scaling_step_size = 123
65+
}
66+
67+
alb_name = "your-alb-name"
68+
target_group_name = "your-alb-target-group-name"
69+
target_group_protocol = "HTTP"
70+
target_group_health_check = {
71+
path = "/path/to/health/check"
72+
}
73+
listener_port = 123
74+
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
75+
security_group_alb = "your-alb-sg-name"
76+
77+
s3_bucket_force_destroy = true
78+
79+
base_domain = "example.com"
80+
domain_name = "your-service.example.com"
81+
region = "us-east-1"
82+
route53_assume_role_arn = "arn:aws:iam::123456789012:role/Route53CrossAccountRole"
83+
```
84+
85+
## Usage
86+
87+
To run this example, you will need to execute the commands:
88+
89+
```bash
90+
terraform init
91+
terraform plan
92+
terraform apply
93+
```
94+
95+
Please note that this example may create resources that can incur monetary charges on your AWS bill. You can run `terraform destroy` when you no longer need the resources.
96+
97+
## Requirements
98+
99+
| Name | Version |
100+
|------|---------|
101+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.6.0 |
102+
103+
## Providers
104+
105+
| Name | Version |
106+
|------|---------|
107+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.62.0 |
108+
109+
## Modules
110+
111+
| Name | Source | Version |
112+
|------|--------|---------|
113+
| <a name="module_ecs_deployment"></a> [ecs\_deployment](#module\_ecs\_deployment) | ../../ | n/a |
114+
115+
## Resources
116+
117+
| Name | Type |
118+
|------|------|
119+
| [aws_security_group.alb_allow_all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
120+
| [aws_route53_zone.base_domain](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/route53_zone) | data source |
121+
122+
## Inputs
123+
124+
| Name | Description | Type | Default | Required |
125+
|------|-------------|------|---------|:--------:|
126+
| <a name="input_alb_name"></a> [alb\_name](#input\_alb\_name) | Name of the application load balancer | `string` | n/a | yes |
127+
| <a name="input_asg_arn"></a> [asg\_arn](#input\_asg\_arn) | ARN of the Auto Scaling group | `string` | n/a | yes |
128+
| <a name="input_base_domain"></a> [base\_domain](#input\_base\_domain) | Base domain for ACM | `string` | n/a | yes |
129+
| <a name="input_capacity_provider_managed_scaling"></a> [capacity\_provider\_managed\_scaling](#input\_capacity\_provider\_managed\_scaling) | Managed scaling configuration for the Capacity Provider | `any` | n/a | yes |
130+
| <a name="input_capacity_provider_name"></a> [capacity\_provider\_name](#input\_capacity\_provider\_name) | Name of the Capacity Provider | `string` | n/a | yes |
131+
| <a name="input_cluster_name"></a> [cluster\_name](#input\_cluster\_name) | Name of the ECS cluster | `string` | n/a | yes |
132+
| <a name="input_container_cpu"></a> [container\_cpu](#input\_container\_cpu) | CPU units to allocate to the container | `number` | n/a | yes |
133+
| <a name="input_container_essential"></a> [container\_essential](#input\_container\_essential) | Essential flag for the container | `bool` | n/a | yes |
134+
| <a name="input_container_image"></a> [container\_image](#input\_container\_image) | Image of the container | `string` | n/a | yes |
135+
| <a name="input_container_memory"></a> [container\_memory](#input\_container\_memory) | Memory in MB to allocate to the container | `number` | n/a | yes |
136+
| <a name="input_container_name"></a> [container\_name](#input\_container\_name) | Name of the container | `string` | n/a | yes |
137+
| <a name="input_container_port"></a> [container\_port](#input\_container\_port) | Port on which the container will listen | `number` | n/a | yes |
138+
| <a name="input_container_port_mappings"></a> [container\_port\_mappings](#input\_container\_port\_mappings) | Port mappings for the container | `any` | n/a | yes |
139+
| <a name="input_container_readonly_root_filesystem"></a> [container\_readonly\_root\_filesystem](#input\_container\_readonly\_root\_filesystem) | Whether the root filesystem is readonly for the container | `bool` | n/a | yes |
140+
| <a name="input_domain_name"></a> [domain\_name](#input\_domain\_name) | Domain name for ACM | `string` | n/a | yes |
141+
| <a name="input_listener_port"></a> [listener\_port](#input\_listener\_port) | Port for the ALB listener | `number` | n/a | yes |
142+
| <a name="input_private_subnets"></a> [private\_subnets](#input\_private\_subnets) | List of private subnet IDs | `list(string)` | n/a | yes |
143+
| <a name="input_public_subnets"></a> [public\_subnets](#input\_public\_subnets) | List of public subnet IDs | `list(string)` | n/a | yes |
144+
| <a name="input_s3_bucket_force_destroy"></a> [s3\_bucket\_force\_destroy](#input\_s3\_bucket\_force\_destroy) | (Optional, Default:false) Boolean that indicates all objects (including any locked objects) should be deleted from the bucket when the bucket is destroyed so that the bucket can be destroyed without error. | `bool` | n/a | yes |
145+
| <a name="input_security_group_alb"></a> [security\_group\_alb](#input\_security\_group\_alb) | Name of the security group for ALB | `string` | n/a | yes |
146+
| <a name="input_service_desired_count"></a> [service\_desired\_count](#input\_service\_desired\_count) | Desired count for the ECS Service | `number` | n/a | yes |
147+
| <a name="input_service_network_configuration_security_groups"></a> [service\_network\_configuration\_security\_groups](#input\_service\_network\_configuration\_security\_groups) | Security Groups for the ECS Service's Network Configuration | `list(string)` | n/a | yes |
148+
| <a name="input_ssl_policy"></a> [ssl\_policy](#input\_ssl\_policy) | SSL policy for the ALB | `string` | n/a | yes |
149+
| <a name="input_target_group_health_check"></a> [target\_group\_health\_check](#input\_target\_group\_health\_check) | Health check configuration for the target group | `any` | n/a | yes |
150+
| <a name="input_target_group_name"></a> [target\_group\_name](#input\_target\_group\_name) | Name of the target group | `string` | n/a | yes |
151+
| <a name="input_target_group_protocol"></a> [target\_group\_protocol](#input\_target\_group\_protocol) | Protocol to use with the target group | `string` | n/a | yes |
152+
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | VPC ID where the resources will be deployed | `string` | n/a | yes |
153+
154+
## Outputs
155+
156+
| Name | Description |
157+
|------|-------------|
158+
| <a name="output_acm_amazon_issued_certificate_arn"></a> [acm\_amazon\_issued\_certificate\_arn](#output\_acm\_amazon\_issued\_certificate\_arn) | ARN of the ACM Amazon-issued certificate for the base domain |
159+
| <a name="output_alb_allow_all_sg_id"></a> [alb\_allow\_all\_sg\_id](#output\_alb\_allow\_all\_sg\_id) | ID of the Security Group for Application Load Balancer to allow all traffic from any source |
160+
| <a name="output_alb_arn"></a> [alb\_arn](#output\_alb\_arn) | ARN of the Application Load Balancer ECS Service |
161+
| <a name="output_ecs_capacity_provider_arn"></a> [ecs\_capacity\_provider\_arn](#output\_ecs\_capacity\_provider\_arn) | ARN of the ECS Capacity Provider |
162+
| <a name="output_ecs_capacity_provider_id"></a> [ecs\_capacity\_provider\_id](#output\_ecs\_capacity\_provider\_id) | Identifier of the ECS Capacity Provider |
163+
| <a name="output_ecs_cluster_capacity_providers_id"></a> [ecs\_cluster\_capacity\_providers\_id](#output\_ecs\_cluster\_capacity\_providers\_id) | Identifier of the ECS Cluster Capacity Providers |
164+
| <a name="output_ecs_service_arn"></a> [ecs\_service\_arn](#output\_ecs\_service\_arn) | ARN of the ECS Service |
165+
| <a name="output_listener_arn"></a> [listener\_arn](#output\_listener\_arn) | ARN of the ALB Listener forwarding to container instances |
166+
| <a name="output_listener_id"></a> [listener\_id](#output\_listener\_id) | Identifier of the ALB Listener forwarding to container instances |
167+
| <a name="output_target_group_arn"></a> [target\_group\_arn](#output\_target\_group\_arn) | ARN of the Target Group instances |
168+
| <a name="output_target_group_id"></a> [target\_group\_id](#output\_target\_group\_id) | Identifier of the Target Group instances |
169+
| <a name="output_task_definition_arn"></a> [task\_definition\_arn](#output\_task\_definition\_arn) | ARN of the ECS Task Definition |
170+
<!-- END_TF_DOCS -->

0 commit comments

Comments
 (0)