https://github.com/sourcefuse/terraform-aws-arc-ec2-autoscale-group
https://github.com/sourcefuse/terraform-aws-arc-ec2-autoscale-group
Last synced: 4 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/sourcefuse/terraform-aws-arc-ec2-autoscale-group
- Owner: sourcefuse
- License: apache-2.0
- Created: 2025-04-23T13:19:55.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-04-30T12:10:51.000Z (about 1 year ago)
- Last Synced: 2025-08-01T05:55:58.743Z (11 months ago)
- Language: HCL
- Size: 15.9 MB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README

# [terraform-aws-arc-ec2-autoscale-group](https://github.com/sourcefuse/terraform-aws-arc-ec2-autoscale-group)
 
[](https://sonarcloud.io/summary/new_code?id=sourcefuse_terraform-aws-arc-ec2-autoscale-group)
[](https://github.com/sourcefuse/terraform-aws-arc-ec2-autoscale-group/actions/workflows/snyk.yaml)
## Overview
SourceFuse's AWS Reference Architecture Terraform module leverages the terraform-aws-modules/terraform-aws-arc-ec2-autoscale-group GitHub repository to enable streamlined provisioning and management of EC2 Auto Scaling Groups. This module facilitates dynamic scaling of EC2 instances based on demand, ensuring high availability and cost efficiency for workloads. It supports customizable launch templates, instance profiles, and scaling policies, allowing flexible configuration tailored to diverse application needs. Integrated with CloudWatch monitoring and load balancing options, the module ensures resilient and performant infrastructure on AWS.
### Prerequisites
Before using this module, ensure you have the following:
- AWS credentials configured.
- Terraform installed.
- A working knowledge of Terraform.
- Network
## Getting Started
1. **Define the Module**
Initially, it's essential to define a Terraform module, which is organized as a distinct directory encompassing Terraform configuration files. Within this module directory, input variables and output values must be defined in the variables.tf and outputs.tf files, respectively. The following illustrates an example directory structure:
```plaintext
asg/
|-- main.tf
|-- variables.tf
|-- outputs.tf
```
2. **Define Input Variables**
Inside the `variables.tf` or in `*.tfvars` file, you should define values for the variables that the module requires.
3. **Use the Module in Your Main Configuration**
In your main Terraform configuration file (e.g., main.tf), you can use the module. Specify the source of the module, and version, For Example
```hcl
module "asg" {
source = "sourcefuse/arc-ec2-autoscale-group/aws"
version = "0.0.1"
launch_template = local.launch_template
asg = local.asg_config
security_group_data = local.security_group_data
security_group_name = local.security_group_name
vpc_id = data.aws_vpc.default.id
autoscaling_notification_enabled = local.autoscaling_notification_enabled
autoscaling_notification_types = local.autoscaling_notification_types
autoscaling_sns_topic_arn = local.autoscaling_sns_topic_arn
schedules = local.schedules
autoscaling_policy = local.autoscaling_policy
predictive_scaling_configuration = local.predictive_scaling_configuration
create_autoscaling_attachment = local.create_autoscaling_attachment
autoscaling_attachments = local.autoscaling_attachments
instance_profile_name = local.instance_profile_name
tags = module.tags.tags
}
```
4. **Output Values**
Inside the `outputs.tf` file of the module, you can define output values that can be referenced in the main configuration. For example:
```hcl
output "name" {
description = "Name of the Auto Scaling Group"
value = module.asg.name
}
output "asg_arn" {
description = "ARN of the Auto Scaling Group"
value = module.asg.asg_arn
}
```
5. **Execute Terraform Commands**
After defining your main configuration, navigate to the directory containing your Terraform files and run the following commands:
```bash
terraform init
terraform apply
```
6. **Review and Confirm**
Terraform will display a plan showing the changes it intends to make. Review the plan and confirm by typing 'yes' when prompted.
## Requirements
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.5.0 |
| [aws](#requirement\_aws) | ~> 5.85 |
## Providers
| Name | Version |
|------|---------|
| [aws](#provider\_aws) | 5.96.0 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| [arc\_security\_group](#module\_arc\_security\_group) | sourcefuse/arc-security-group/aws | 0.0.1 |
## Resources
| Name | Type |
|------|------|
| [aws_autoscaling_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_attachment) | resource |
| [aws_autoscaling_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_group) | resource |
| [aws_autoscaling_notification.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_notification) | resource |
| [aws_autoscaling_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_policy) | resource |
| [aws_autoscaling_schedule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_schedule) | resource |
| [aws_autoscaling_traffic_source_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_traffic_source_attachment) | resource |
| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_launch_template.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [asg](#input\_asg) | Configuration map for Auto Scaling Group |
object({
name = optional(string)
min_size = number
max_size = number
desired_capacity = optional(number)
desired_capacity_type = optional(string)
vpc_zone_identifier = optional(list(string))
availability_zones = optional(list(string))
min_elb_capacity = optional(number)
wait_for_elb_capacity = optional(number)
wait_for_capacity_timeout = optional(string)
capacity_rebalance = optional(bool)
context = optional(string)
placement_group = optional(string)
health_check_type = optional(string)
health_check_grace_period = optional(number)
protect_from_scale_in = optional(bool)
default_cooldown = optional(number)
default_instance_warmup = optional(number)
force_delete = optional(bool)
max_instance_lifetime = optional(number)
metrics_granularity = optional(string)
enabled_metrics = optional(list(string))
termination_policies = optional(list(string))
suspended_processes = optional(list(string))
service_linked_role_arn = optional(string)
instance_generations = optional(bool)
tags = optional(list(map(string)))
availability_zone_distribution = optional(object({
capacity_distribution_strategy = string
}))
initial_lifecycle_hook = optional(list(object({
name = string
lifecycle_transition = string
default_result = optional(string)
heartbeat_timeout = optional(number)
notification_metadata = optional(string)
notification_target_arn = optional(string)
role_arn = optional(string)
})))
instance_maintenance_policy = optional(object({
min_healthy_percentage = optional(number)
max_healthy_percentage = optional(number)
}))
mixed_instances_policy = optional(object({
launch_template = object({
launch_template_specification = object({
version = string
})
override = optional(list(object({
instance_type = optional(string)
weighted_capacity = optional(string)
instance_requirements = optional(object({
accelerator_count = optional(object({
min = number,
max = number
})),
accelerator_manufacturers = optional(list(string)),
accelerator_names = optional(list(string)),
accelerator_total_memory_mib = optional(object({
min = number,
max = number
})),
accelerator_types = optional(list(string)),
allowed_instance_types = optional(list(string)),
bare_metal = optional(string),
baseline_ebs_bandwidth_mbps = optional(object({
min = number,
max = number
})),
burstable_performance = optional(string),
cpu_manufacturers = optional(list(string)),
excluded_instance_types = optional(list(string)),
instance_generations = optional(list(string)),
local_storage = optional(string),
local_storage_types = optional(list(string)),
max_spot_price_as_percentage_of_optimal_on_demand_price = optional(number),
memory_gib_per_vcpu = optional(object({
min = number,
max = number
})),
memory_mib = optional(object({
min = number,
max = number
})),
network_bandwidth_gbps = optional(object({
min = number,
max = number
})),
network_interface_count = optional(object({
min = number,
max = number
})),
on_demand_max_price_percentage_over_lowest_price = optional(number),
require_hibernate_support = optional(bool),
spot_max_price_percentage_over_lowest_price = optional(number),
total_local_storage_gb = optional(object({
min = number,
max = number
})),
vcpu_count = optional(object({
min = number,
max = number
}))
}))
})))
})
instances_distribution = optional(object({
on_demand_allocation_strategy = optional(string)
on_demand_base_capacity = optional(number)
on_demand_percentage_above_base_capacity = optional(number)
spot_allocation_strategy = optional(string)
spot_instance_pools = optional(number)
spot_max_price = optional(string)
}))
}))
warm_pool = optional(object({
max_group_prepared_capacity = optional(number)
min_size = optional(number)
pool_state = optional(string)
instance_reuse_policy = optional(object({
reuse_on_scale_in = optional(bool)
}))
}))
instance_refresh = optional(list(object({
strategy = string
triggers = optional(list(string))
preferences = optional(object({
checkpoint_delay = optional(number)
checkpoint_percent = optional(number)
instance_warmup = optional(number)
min_healthy_percentage = optional(number)
max_healthy_percentage = optional(number)
scale_in_protected_instances = optional(string)
standby_instances = optional(string)
auto_rollback = optional(bool)
}))
})))
}) | n/a | yes |
| [autoscaling\_attachments](#input\_autoscaling\_attachments) | Map of autoscaling attachment configurations | map(object({
autoscaling_group_name = string
lb_target_group_arn = optional(string)
elb = optional(string)
})) | `{}` | no |
| [autoscaling\_notification\_enabled](#input\_autoscaling\_notification\_enabled) | Boolean flag to enable or disable autoscaling notifications | `bool` | `false` | no |
| [autoscaling\_notification\_types](#input\_autoscaling\_notification\_types) | List of notification types for the Auto Scaling group | `list(string)` | [
"autoscaling:EC2_INSTANCE_LAUNCH",
"autoscaling:EC2_INSTANCE_TERMINATE",
"autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
"autoscaling:EC2_INSTANCE_TERMINATE_ERROR"
]
| no |
| [autoscaling\_policy](#input\_autoscaling\_policy) | Configuration for the autoscaling policy | object({
name = optional(string)
policy_type = optional(string)
adjustment_type = optional(string)
cooldown = optional(number)
estimated_instance_warmup = optional(number)
scaling_adjustment = optional(number)
metric_aggregation_type = optional(string)
min_adjustment_magnitude = optional(number)
step_adjustment = optional(list(object({
scaling_adjustment = number
metric_interval_lower_bound = optional(number)
metric_interval_upper_bound = optional(number)
})))
target_tracking_configuration = optional(object({
disable_scale_in = optional(bool)
target_value = optional(number)
predefined_metric_specification = optional(object({
predefined_metric_type = string
resource_label = optional(string)
}))
customized_metric_specification = optional(object({
metric_name = string
namespace = string
statistic = string
unit = optional(string)
metric_dimension = optional(list(object({
name = string
value = string
})))
}))
}))
}) | `{}` | no |
| [autoscaling\_sns\_topic\_arn](#input\_autoscaling\_sns\_topic\_arn) | ARN of the SNS topic to send Auto Scaling notifications to | `string` | n/a | yes |
| [create\_autoscaling\_attachment](#input\_create\_autoscaling\_attachment) | Whether to create autoscaling attachments | `bool` | `false` | no |
| [create\_traffic\_source\_attachment](#input\_create\_traffic\_source\_attachment) | Whether to create traffic source attachment for the auto scaling group | `bool` | `false` | no |
| [instance\_profile\_name](#input\_instance\_profile\_name) | The name of the IAM instance profile | `string` | `"asg-instance-profile"` | no |
| [launch\_template](#input\_launch\_template) | Configuration for the EC2 Launch Template | object({
name = string
description = optional(string)
image_id = string
instance_type = string
user_data = optional(string)
disable_api_stop = optional(bool)
default_version = optional(string)
update_default_version = optional(bool)
disable_api_termination = optional(bool)
ebs_optimized = optional(bool)
block_device_mappings = optional(list(object({
device_name = string
no_device = optional(string)
virtual_name = optional(string)
ebs = optional(object({
volume_size = optional(number)
delete_on_termination = optional(bool)
encrypted = optional(bool)
iops = optional(number)
kms_key_id = optional(string)
snapshot_id = optional(string)
throughput = optional(number)
volume_type = optional(string)
}))
})))
cpu_options = optional(object({
core_count = optional(number)
amd_sev_snp = optional(bool)
threads_per_core = optional(number)
}))
capacity_reservation_specification = optional(object({
capacity_reservation_preference = optional(string)
capacity_reservation_target = optional(object({
capacity_reservation_id = optional(string)
capacity_reservation_resource_group_arn = optional(string)
}))
}))
credit_specification = optional(object({
cpu_credits = optional(string)
}))
elastic_inference_accelerator = optional(object({
type = string
}))
enclave_options = optional(object({
enabled = bool
}))
hibernation_options = optional(object({
configured = bool
}))
elastic_gpu_specifications = optional(list(object({
type = string
})))
iam_instance_profile = optional(object({
arn = optional(string)
name = optional(string)
}))
instance_requirements = optional(object({
accelerator_count = optional(object({ min = number, max = number }))
accelerator_manufacturers = optional(list(string))
accelerator_names = optional(list(string))
accelerator_total_memory_mib = optional(object({ min = number, max = number }))
accelerator_types = optional(list(string))
allowed_instance_types = optional(list(string))
bare_metal = optional(string)
baseline_ebs_bandwidth_mbps = optional(object({ min = number, max = number }))
burstable_performance = optional(string)
cpu_manufacturers = optional(list(string))
excluded_instance_types = optional(list(string))
instance_generations = optional(list(string))
local_storage = optional(string)
local_storage_types = optional(list(string))
max_spot_price_as_percentage_of_optimal_on_demand_price = optional(number)
memory_gib_per_vcpu = optional(object({ min = number, max = number }))
memory_mib = optional(object({ min = number, max = number }))
network_interface_count = optional(object({ min = number, max = number }))
on_demand_max_price_percentage_over_lowest_price = optional(number)
require_hibernate_support = optional(bool)
spot_max_price_percentage_over_lowest_price = optional(number)
total_local_storage_gb = optional(object({ min = number, max = number }))
vcpu_count = optional(object({ min = number, max = number }))
}))
kernel_id = optional(string)
ram_disk_id = optional(string)
instance_initiated_shutdown_behavior = optional(string)
monitoring = optional(object({
enabled = bool
}))
maintenance_options = optional(object({
auto_recovery = string
}))
license_specification = optional(object({
license_configuration_arn = optional(string)
}))
instance_market_options = optional(object({
market_type = string
spot_options = optional(object({
block_duration_minutes = optional(number)
instance_interruption_behavior = optional(string)
max_price = optional(string)
spot_instance_type = optional(string)
valid_until = optional(string)
}))
}))
network_interfaces = optional(list(object({
associate_public_ip_address = optional(bool)
description = optional(string)
device_index = optional(number)
interface_type = optional(string)
ipv4_prefixes = optional(list(string))
ipv4_prefix_count = optional(number)
ipv4_address_count = optional(number)
ipv6_prefix_count = optional(number)
ipv6_prefixes = optional(list(string))
ipv4_addresses = optional(list(string))
ipv6_addresses = optional(list(string))
ipv6_address_count = optional(number)
network_interface_id = optional(string)
network_card_index = optional(number)
private_ip_address = optional(string)
primary_ipv6 = optional(bool)
security_groups = optional(list(string))
subnet_id = optional(string)
delete_on_termination = optional(bool)
connection_tracking_specification = optional(object({
tcp_established_timeout = optional(number)
udp_stream_timeout = optional(number)
udp_timeout = optional(number)
}))
})))
metadata_options = optional(object({
http_endpoint = optional(string)
http_tokens = optional(string)
http_put_response_hop_limit = optional(number)
http_protocol_ipv6 = optional(string)
instance_metadata_tags = optional(string)
}))
placement = optional(object({
availability_zone = optional(string)
affinity = optional(string)
group_name = optional(string)
host_id = optional(string)
host_resource_group_arn = optional(string)
partition_number = optional(number)
spread_domain = optional(string)
tenancy = optional(string)
}))
private_dns_name_options = optional(object({
enable_resource_name_dns_a_record = optional(bool)
enable_resource_name_dns_aaaa_record = optional(bool)
hostname_type = optional(string)
}))
tag_specifications = optional(object({
resource_type = optional(string)
tags = optional(string)
}))
}) | n/a | yes |
| [predictive\_scaling\_configuration](#input\_predictive\_scaling\_configuration) | Predictive scaling configuration | object({
mode = optional(string)
scheduling_buffer_time = optional(number)
max_capacity_breach_behavior = optional(string)
max_capacity_buffer = optional(number)
metric_specification = list(object({
target_value = number
predefined_metric_pair_specification = optional(object({
predefined_metric_type = string
resource_label = optional(string)
}))
predefined_load_metric_specification = optional(object({
predefined_metric_type = string
resource_label = optional(string)
}))
predefined_scaling_metric_specification = optional(object({
predefined_metric_type = string
resource_label = optional(string)
}))
customized_scaling_metric_specification = optional(object({
metric_data_queries = list(object({
id = string
expression = optional(string)
label = optional(string)
return_data = optional(bool)
metric_stat = optional(object({
stat = string
unit = optional(string)
metric = object({
metric_name = string
namespace = string
dimensions = optional(list(object({
name = string
value = string
})))
})
}))
}))
}))
customized_load_metric_specification = optional(object({
metric_data_queries = list(object({
id = string
expression = optional(string)
label = optional(string)
return_data = optional(bool)
metric_stat = optional(object({
stat = string
unit = optional(string)
metric = object({
metric_name = string
namespace = string
dimensions = optional(list(object({
name = string
value = string
})))
})
}))
}))
}))
customized_capacity_metric_specification = optional(object({
metric_data_queries = list(object({
id = string
expression = optional(string)
label = optional(string)
return_data = optional(bool)
metric_stat = optional(object({
stat = string
unit = optional(string)
metric = object({
metric_name = string
namespace = string
dimensions = optional(list(object({
name = string
value = string
})))
})
}))
}))
}))
}))
}) | `null` | no |
| [schedules](#input\_schedules) | List of Auto Scaling schedules | list(object({
scheduled_action_name = string
desired_capacity = optional(number)
min_size = optional(number)
max_size = optional(number)
start_time = optional(string)
end_time = optional(string)
recurrence = optional(string)
time_zone = optional(string)
})) | `[]` | no |
| [security\_group\_data](#input\_security\_group\_data) | (optional) Security Group data | object({
security_group_ids_to_attach = optional(list(string), [])
create = optional(bool, true)
description = optional(string, null)
ingress_rules = optional(list(object({
description = optional(string, null)
cidr_block = optional(string, null)
source_security_group_id = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
self = optional(bool, false)
})), [])
egress_rules = optional(list(object({
description = optional(string, null)
cidr_block = optional(string, null)
destination_security_group_id = optional(string, null)
from_port = number
ip_protocol = string
to_port = string
prefix_list_id = optional(string, null)
})), [])
}) | {
"create": false
} | no |
| [security\_group\_name](#input\_security\_group\_name) | alb security group name | `string` | n/a | yes |
| [security\_groups](#input\_security\_groups) | n/a | `list(string)` | `[]` | no |
| [tags](#input\_tags) | Tags to apply to resources | `map(string)` | {
"Environment": "dev",
"Name": "arc"
} | no |
| [traffic\_sources](#input\_traffic\_sources) | List of traffic sources to attach to the Auto Scaling group | list(object({
identifier = string
type = string
})) | `[]` | no |
| [vpc\_id](#input\_vpc\_id) | The VPC ID for the resources | `string` | n/a | yes |
## Outputs
| Name | Description |
|------|-------------|
| [asg\_arn](#output\_asg\_arn) | ARN of the Auto Scaling Group |
| [asg\_id](#output\_asg\_id) | ID of the Auto Scaling Group |
| [availability\_zones](#output\_availability\_zones) | Availability Zones used by the Auto Scaling Group |
| [desired\_capacity](#output\_desired\_capacity) | Desired capacity of the Auto Scaling Group |
| [enabled\_metrics](#output\_enabled\_metrics) | List of enabled metrics for the ASG |
| [iam\_instance\_profile\_arn](#output\_iam\_instance\_profile\_arn) | ARN of the IAM instance profile |
| [iam\_role\_name](#output\_iam\_role\_name) | The name of the IAM role attached to the instance profile |
| [launch\_template\_arn](#output\_launch\_template\_arn) | The ARN of the launch template |
| [launch\_template\_default\_version](#output\_launch\_template\_default\_version) | The default version of the launch template |
| [launch\_template\_id](#output\_launch\_template\_id) | The ID of the launch template |
| [launch\_template\_latest\_version](#output\_launch\_template\_latest\_version) | The latest version of the launch template |
| [launch\_template\_name](#output\_launch\_template\_name) | The name of the launch template |
| [name](#output\_name) | Name of the Auto Scaling Group |
## Versioning
This project uses a `.version` file at the root of the repo which the pipeline reads from and does a git tag.
When you intend to commit to `main`, you will need to increment this version. Once the project is merged,
the pipeline will kick off and tag the latest git commit.
## Development
### Prerequisites
- [terraform](https://learn.hashicorp.com/terraform/getting-started/install#installing-terraform)
- [terraform-docs](https://github.com/segmentio/terraform-docs)
- [pre-commit](https://pre-commit.com/#install)
- [golang](https://golang.org/doc/install#install)
- [golint](https://github.com/golang/lint#installation)
### Configurations
- Configure pre-commit hooks
```sh
pre-commit install
```
### Versioning
while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch
For Example
```sh
git commit -m "your commit message #major"
```
By specifying this , it will bump the version and if you don't specify this in your commit message then by default it will consider patch and will bump that accordingly
### Tests
- Tests are available in `test` directory
- Configure the dependencies
```sh
cd test/
go mod init github.com/sourcefuse/terraform-aws-refarch-ec2-autoscale-group
go get github.com/gruntwork-io/terratest/modules/terraform
```
- Now execute the test
```sh
go test -timeout 30m
```
## Authors
This project is authored by:
- SourceFuse ARC Team