Thanks to visit codestin.com
Credit goes to github.com

Skip to content

sourcefuse/terraform-aws-arc-ec2-autoscale-group

Repository files navigation

Module Structure

Latest Release Last Updated Terraform GitHub Actions

Quality gate

Known Vulnerabilities

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:

asg/
|-- main.tf
|-- variables.tf
|-- outputs.tf
  1. Define Input Variables

Inside the variables.tf or in *.tfvars file, you should define values for the variables that the module requires.

  1. 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
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
}
  1. 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:

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
}
  1. Execute Terraform Commands

After defining your main configuration, navigate to the directory containing your Terraform files and run the following commands:

terraform init
terraform apply
  1. 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 >= 1.5.0
aws ~> 5.85

Providers

Name Version
aws 5.96.0

Modules

Name Source Version
arc_security_group sourcefuse/arc-security-group/aws 0.0.1

Resources

Name Type
aws_autoscaling_attachment.this resource
aws_autoscaling_group.this resource
aws_autoscaling_notification.this resource
aws_autoscaling_policy.this resource
aws_autoscaling_schedule.this resource
aws_autoscaling_traffic_source_attachment.this resource
aws_iam_instance_profile.this resource
aws_iam_role.this resource
aws_launch_template.this resource

Inputs

Name Description Type Default Required
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 Map of autoscaling attachment configurations
map(object({
autoscaling_group_name = string
lb_target_group_arn = optional(string)
elb = optional(string)
}))
{} no
autoscaling_notification_enabled Boolean flag to enable or disable autoscaling notifications bool false no
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 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 ARN of the SNS topic to send Auto Scaling notifications to string n/a yes
create_autoscaling_attachment Whether to create autoscaling attachments bool false no
create_traffic_source_attachment Whether to create traffic source attachment for the auto scaling group bool false no
instance_profile_name The name of the IAM instance profile string "asg-instance-profile" no
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 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 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 (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 alb security group name string n/a yes
security_groups n/a list(string) [] no
tags Tags to apply to resources map(string)
{
"Environment": "dev",
"Name": "arc"
}
no
traffic_sources List of traffic sources to attach to the Auto Scaling group
list(object({
identifier = string
type = string
}))
[] no
vpc_id The VPC ID for the resources string n/a yes

Outputs

Name Description
asg_arn ARN of the Auto Scaling Group
asg_id ID of the Auto Scaling Group
availability_zones Availability Zones used by the Auto Scaling Group
desired_capacity Desired capacity of the Auto Scaling Group
enabled_metrics List of enabled metrics for the ASG
iam_instance_profile_arn ARN of the IAM instance profile
iam_role_name The name of the IAM role attached to the instance profile
launch_template_arn The ARN of the launch template
launch_template_default_version The default version of the launch template
launch_template_id The ID of the launch template
launch_template_latest_version The latest version of the launch template
launch_template_name The name of the launch template
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

Configurations

  • Configure pre-commit hooks
    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

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
    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
    go test -timeout  30m

Authors

This project is authored by:

  • SourceFuse ARC Team

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published