├── .circleci
└── config.yml
├── .github
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .terraform-version
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── examples
├── basic_usage.tf
├── custom_ami.tf
├── custom_cw_config.tf
└── text
│ └── linux_cw_agent_param.json
├── main.tf
├── outputs.tf
├── tests
└── test1
│ ├── main.tf
│ └── variables.tf
├── text
├── amazon_linux_userdata.sh
├── debian_userdata.sh
├── linux_cw_agent_param.json
├── rhel_centos_7_userdata.sh
├── rhel_centos_8_userdata.sh
├── ubuntu_userdata.sh
├── windows_cw_agent_param.json
└── windows_userdata.ps1
└── variables.tf
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | test:
4 | docker:
5 | - image: 891714082543.dkr.ecr.us-west-2.amazonaws.com/rackspace-tf-toolbox
6 | working_directory: ~/
7 | steps:
8 | - attach_workspace:
9 | at: ~/workspace
10 | - checkout:
11 | path: ~/branches/${CIRCLE_BRANCH}
12 | - run:
13 | name: Run Test
14 | command: MODULE_CI_JOB='test' python3 orchestrate.py
15 | - run:
16 | name: destroy
17 | command: cd ~ && ~/bin/destroy.sh && ~/bin/destroy_s3_buckets.sh # must succeed or we have something to clean up manually
18 | when: always
19 | - persist_to_workspace:
20 | root: ~/workspace
21 | paths:
22 | - plan_results/*
23 | - artifacts/*
24 | check_destruction:
25 | docker:
26 | - image: 891714082543.dkr.ecr.us-west-2.amazonaws.com/rackspace-tf-toolbox
27 | working_directory: ~/
28 | steps:
29 | - attach_workspace:
30 | at: ~/workspace
31 | - checkout:
32 | path: ~/module
33 | - run:
34 | name: Check Destruction
35 | command: MODULE_CI_JOB='check_destruction' python3 orchestrate.py
36 | - store_artifacts:
37 | path: ~/workspace/artifacts
38 |
39 |
40 | workflows:
41 | version: 2
42 | build_and_test:
43 | jobs:
44 | - test:
45 | filters:
46 | branches:
47 | ignore: master
48 | - check_destruction:
49 | requires:
50 | - test
51 | filters:
52 | branches:
53 | ignore: master
54 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ##### Corresponding Issue(s):
2 | - PRs should have a corresponding issue. If no issue exists, provide details in the **Reason for Change(s)** section
3 |
4 | ##### Summary of change(s):
5 |
6 | ##### Reason for Change(s):
7 |
8 | - If a bug, describe error scenario, including expected behavior and actual behavior.
9 |
10 | - If an enhancement, describe the use case and the perceived benefit(s).
11 |
12 | ##### Will the change trigger resource destruction or replacement? If yes, please provide justification:
13 |
14 | ##### Does this update/change involve issues with other external modules? If so, please describe the scenario.
15 |
16 | ##### If input variables or output variables have changed or has been added, have you updated the README?
17 |
18 | ##### Do examples need to be updated based on changes?
19 |
20 | ##### Note to the PR requester about Closing PR's
21 | Please message the person that opened the issue when auto closing it on slack, as well as any other stake holders of deep interest. Only close the issue if you believe that the issue is fully resolved with this PR.
22 |
23 | #### This PR may auto close the issue associated with it. If you feel the issue is not resolved please reopen the issue.
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Local .terraform directories
2 | **/.terraform/*
3 |
4 | # .tfstate files
5 | *.tfstate
6 | *.tfstate.*
7 |
8 | # .tfvars files
9 | *.tfvars
10 |
11 | # Plans
12 | *.plans
13 |
14 | # Secrets
15 | secrets.tf
16 |
17 | # Mac
18 | .DS_Store
19 |
20 | # Idea
21 | .idea/*
--------------------------------------------------------------------------------
/.terraform-version:
--------------------------------------------------------------------------------
1 | 1.0.0
2 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | This document is a set of guidelines to contribute to the [Rackspace](https://www.rackspace.com) [Terraform](https://www.terraform.io/) modules. These modules were created to enable and empower our Managed Infrastructure as Code product. While these modules are designed for Rackspace environments, we hope they may be of use to the community at large.
4 |
5 | ## Reporting issues
6 |
7 | Rackspace customers should open a normal Rackspace support ticket to report any problems or feedback for these modules. Our support Rackers will then work with you and our product team to address those issues.
8 |
9 | ## Submitting Changes
10 |
11 | Pull requests are welcome. Currently our CI solution cannot run against pull requests from forks. Despite this, these submissions are still welcome. All pull requests will be evaluated against Rackspace best practices, and after approval, will be migrated to a branch for testing.
12 |
13 | For significant or critical features, a new test should be created, or if appropriate, and existing test should be updated. This will serve to ensure the any failures related to the feature are caught.
14 |
15 | When submitting a pull request please explain the changes in detail, and try to minimize the scope to related changes. For example, changes resolving separate bugs should be broken out into separate pull requests. If there are relevant documentation or references, such as terraform bug reports, links to those references are greatly appreciated.
16 |
17 | ## Testing
18 |
19 | Pull requests must pass a linting and build test prior to acceptance. This test ensures all submissions will produce a stable and working deployment. In addition, our CI jobs will run a check_destruction test to help determine if any breaking changes will occur with this change. This test will show a failed result if breaking changes are detected, but this will not prevent the submission from being approved.
20 |
21 | ## Coding and Style guidelines
22 |
23 | All submissions should comply with the coding and style guides outlined at [General Terraform Style Guide](https://manage.rackspace.com/aws/docs/product-guide/miac/terraform-standards.html#general-terraform-style-guide) and [Rackspace Module Standards](https://manage.rackspace.com/aws/docs/product-guide/miac/terraform-standards.html#rackspace-module-). CI testing will run and flag code that does not meet these defined standards whenever possible.
24 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2018 Rackspace, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > [!CAUTION]
2 | > This project is end of life. This repo will be deleted on June 2nd 2025.
3 |
4 | # aws-terraform-ec2\_asg
5 |
6 | This module creates one or more autoscaling groups.
7 |
8 | ## Basic Usage
9 |
10 | ```HCL
11 | module "asg" {
12 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-ec2_asg//?ref=v0.12.16"
13 |
14 | ec2_os = "amazon2"
15 | name = "my_asg"
16 | security_groups = [module.sg.private_web_security_group_id]
17 | subnets = module.vpc.private_subnets
18 | }
19 | ```
20 |
21 | Full working references are available at [examples](examples)
22 |
23 | ## Other TF Modules Used
24 |
25 | Using [aws-terraform-cloudwatch\_alarm](https://github.com/rackspace-infrastructure-automation/aws-terraform-cloudwatch_alarm) to create the following CloudWatch Alarms:
26 | - group\_terminating\_instances
27 |
28 | ## Terraform 0.12 upgrade
29 |
30 | Several changes were required while adding terraform 0.12 compatibility. The following changes should
31 | made when upgrading from a previous release to version 0.12.0 or higher.
32 |
33 | ### Module variables
34 |
35 | The following module variables were updated to better meet current Rackspace style guides:
36 |
37 | - `security_group_list` -> `security_groups`
38 | - `resource_name` -> `name`
39 |
40 | The following variables are no longer neccessary and were removed
41 |
42 | - `additional_ssm_bootstrap_step_count`
43 | - `install_scaleft_agent`
44 |
45 | Several new variables were introduced to provide existing functionality, with a simplified format. The original formmating was also retained to allow easier transition.
46 |
47 | New variables `tags` and `tags_asg` were added to replace the functionality of the `additional_tags` variable. `tags` allows setting tags on all resources, while `tags_asg` sets tags only on the ASG itself. `additional_tags` will continue to work as expected, but will be removed in a future release.
48 |
49 | New variable `ssm_bootstrap_list` was added to allow setting the SSM association steps using objects instead of strings, allowing easier linting and formatting of these lines. The `additional_ssm_bootstrap_list` variable will continue to work, but will be deprecated in a future release.
50 |
51 | ## Requirements
52 |
53 | | Name | Version |
54 | |------|---------|
55 | | terraform | >= 1.0.0 |
56 | | aws | ~> 3.0 |
57 |
58 | ## Providers
59 |
60 | | Name | Version |
61 | |------|---------|
62 | | aws | ~> 3.0 |
63 |
64 | ## Modules
65 |
66 | | Name | Source | Version |
67 | |------|--------|---------|
68 | | group_terminating_instances | git@github.com:rackspace-infrastructure-automation/aws-terraform-cloudwatch_alarm//?ref=v0.12.6 | |
69 |
70 | ## Resources
71 |
72 | | Name |
73 | |------|
74 | | [aws_ami](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/data-sources/ami) |
75 | | [aws_autoscaling_group](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/autoscaling_group) |
76 | | [aws_autoscaling_notification](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/autoscaling_notification) |
77 | | [aws_autoscaling_policy](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/autoscaling_policy) |
78 | | [aws_caller_identity](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/data-sources/caller_identity) |
79 | | [aws_cloudwatch_log_group](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/cloudwatch_log_group) |
80 | | [aws_cloudwatch_metric_alarm](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/cloudwatch_metric_alarm) |
81 | | [aws_iam_instance_profile](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/iam_instance_profile) |
82 | | [aws_iam_policy](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/iam_policy) |
83 | | [aws_iam_policy_document](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/data-sources/iam_policy_document) |
84 | | [aws_iam_role](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/iam_role) |
85 | | [aws_iam_role_policy_attachment](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/iam_role_policy_attachment) |
86 | | [aws_launch_template](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/launch_template) |
87 | | [aws_region](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/data-sources/region) |
88 | | [aws_ssm_association](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/ssm_association) |
89 | | [aws_ssm_document](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/ssm_document) |
90 | | [aws_ssm_parameter](https://registry.terraform.io/providers/hashicorp/aws/3.0/docs/resources/ssm_parameter) |
91 |
92 | ## Inputs
93 |
94 | | Name | Description | Type | Default | Required |
95 | |------|-------------|------|---------|:--------:|
96 | | additional\_ssm\_bootstrap\_list | A list of maps consisting of main step actions, to be appended to SSM associations. Please see usage.tf.example in this repo for examples.
(DEPRECATED) This variable will be removed in future releases in favor of the `ssm_bootstrap_list` variable. | `list(map(string))` | `[]` | no |
97 | | additional\_tags | Additional tags to be added to the ASG instance(s). Format: list of maps. Please see usage.tf.example in this repo for examples.
(DEPRECATED) This variable will be removed in future releases in favor of the `tags` and `tags_asg` variables. | `list(map(string))` | `[]` | no |
98 | | alb\_resource\_label | Enter the ALB and Target group in this format : app/load-balancer-name/load-balancer-id/targetgroup/target-group-name/target-group-id | `string` | `null` | no |
99 | | asg\_count | Number of identical ASG's to deploy | `string` | `"1"` | no |
100 | | asg\_wait\_for\_capacity\_timeout | A maximum duration that Terraform should wait for ASG instances to be healthy before timing out. | `string` | `"10m"` | no |
101 | | backup\_tag\_value | Value of the 'Backup' tag, used to assign to the AWS Backup configuration | `string` | `"False"` | no |
102 | | cloudwatch\_log\_retention | The number of days to retain Cloudwatch Logs for this instance. | `string` | `"30"` | no |
103 | | custom\_cw\_agent\_config\_ssm\_param | SSM Parameter Store name that contains a custom CloudWatch agent configuration that you would like to use as an alternative to the default provided. | `string` | `""` | no |
104 | | customer\_alarms\_cleared | Specifies whether alarms will notify customers when returning to an OK status. | `bool` | `false` | no |
105 | | customer\_alarms\_enabled | Specifies whether alarms will notify customers. Automatically enabled if rackspace\_managed is set to false | `bool` | `false` | no |
106 | | cw\_high\_evaluations | The number of periods over which data is compared to the specified threshold. | `string` | `"3"` | no |
107 | | cw\_high\_operator | Math operator used by CloudWatch for alarms and triggers. | `string` | `"GreaterThanThreshold"` | no |
108 | | cw\_high\_period | Time the specified statistic is applied. Must be in seconds that is also a multiple of 60. | `string` | `"60"` | no |
109 | | cw\_high\_threshold | The value against which the specified statistic is compared. | `string` | `"60"` | no |
110 | | cw\_low\_evaluations | The number of periods over which data is compared to the specified threshold. | `string` | `"3"` | no |
111 | | cw\_low\_operator | Math operator used by CloudWatch for alarms and triggers. | `string` | `"LessThanThreshold"` | no |
112 | | cw\_low\_period | Time the specified statistic is applied. Must be in seconds that is also a multiple of 60. | `string` | `"300"` | no |
113 | | cw\_low\_threshold | The value against which the specified statistic is compared. | `string` | `"30"` | no |
114 | | cw\_scaling\_metric | The metric to be used for scaling. | `string` | `"CPUUtilization"` | no |
115 | | detailed\_monitoring | Enable Detailed Monitoring? true or false | `bool` | `true` | no |
116 | | disable\_scale\_in | Disable scale in to create only a scale-out policy in Target Tracking Policy. | `bool` | `false` | no |
117 | | ec2\_os | Intended Operating System/Distribution of Instance. Valid inputs are: `amazon2`, `amazoneks`, `amazonecs`, `rhel7`, `rhel8`, `centos7`, `ubuntu18`, `ubuntu20`, `windows2012r2`, `windows2016`, `windows2019` | `string` | n/a | yes |
118 | | ec2\_scale\_down\_adjustment | Number of EC2 instances to scale down by at a time. Positive numbers will be converted to negative. | `string` | `"-1"` | no |
119 | | ec2\_scale\_down\_cool\_down | Time in seconds before any further trigger-related scaling can occur. | `string` | `"60"` | no |
120 | | ec2\_scale\_up\_adjustment | Number of EC2 instances to scale up by at a time. | `string` | `"1"` | no |
121 | | ec2\_scale\_up\_cool\_down | Time in seconds before any further trigger-related scaling can occur. | `string` | `"60"` | no |
122 | | enable\_ebs\_optimization | Use EBS Optimized? true or false | `bool` | `false` | no |
123 | | enable\_rolling\_updates | Should this autoscaling group be targeted by the ASG Instance Replacement tool to ensure all instances are using thelatest launch configuration. | `bool` | `true` | no |
124 | | enable\_scaling\_actions | Should this autoscaling group be configured with scaling alarms to manage the desired count. Set this variable to false if another process will manage the desired count, such as EKS Cluster Autoscaler. | `bool` | `true` | no |
125 | | enable\_scaling\_notification | true or false. If 'scaling\_notification\_topic' is set to a non-empty string, this must be set to true. Otherwise, set to false. This variable exists due to a terraform limitation with using count and computed values as conditionals | `bool` | `false` | no |
126 | | enabled\_asg\_metrics | List of ASG metrics desired. This can only contain the following values: `GroupDesiredCapacity`, `GroupInServiceCapacity`, `GroupPendingCapacity`, `GroupMinSize`, `GroupMaxSize`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupStandbyCapacity`, `GroupTerminatingCapacity`, `GroupTerminatingInstances`, `GroupTotalCapacity`, `GroupTotalInstances`. | `list(string)` | `[]` | no |
127 | | encrypt\_primary\_ebs\_volume | Encrypt root EBS Volume? true or false | `bool` | `false` | no |
128 | | encrypt\_secondary\_ebs\_volume | Encrypt secondary EBS Volume? true or false | `bool` | `false` | no |
129 | | environment | Application environment for which this network is being created. Preferred value are Development, Integration, PreProduction, Production, QA, Staging, or Test | `string` | `"Development"` | no |
130 | | final\_userdata\_commands | Commands to be given at the end of userdata for an instance. This should generally not include bootstrapping or ssm install. | `string` | `""` | no |
131 | | health\_check\_grace\_period | Number of seconds grace during which no autoscaling actions will be taken. | `string` | `"300"` | no |
132 | | health\_check\_type | Define the type of healthcheck for the AutoScaling group. | `string` | `"EC2"` | no |
133 | | image\_id | The AMI ID to be used to build the EC2 Instance. If not provided, an AMI ID will be queried with an OS specified in variable ec2\_os. | `string` | `""` | no |
134 | | initial\_userdata\_commands | Commands to be given at the start of userdata for an instance. This should generally not include bootstrapping or ssm install. | `string` | `""` | no |
135 | | install\_codedeploy\_agent | Install codedeploy agent on instance(s)? true or false | `bool` | `false` | no |
136 | | instance\_profile\_override | Optionally provide an instance profile. Any override profile should contain the permissions required for Rackspace support tooling to continue to function if required. | `bool` | `false` | no |
137 | | instance\_profile\_override\_name | Provide an instance profile name. Any override profile should contain the permissions required for Rackspace support tooling to continue to function if required. To use this set `instance_profile_override` to `true`. | `string` | `""` | no |
138 | | instance\_role\_managed\_policy\_arn\_count | The number of policy ARNs provided/set in variable 'instance\_role\_managed\_policy\_arns' | `string` | `"0"` | no |
139 | | instance\_role\_managed\_policy\_arns | List of IAM policy ARNs for the InstanceRole IAM role. IAM ARNs can be found within the Policies section of the AWS IAM console. e.g. ['arn:aws:iam::aws:policy/AmazonEC2FullAccess', 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore', 'arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetRole'] | `list(string)` | `[]` | no |
140 | | instance\_type | EC2 Instance Type e.g. 't2.micro' | `string` | `"t2.micro"` | no |
141 | | instance\_warm\_up\_time | Specify the Instance Warm Up time for Target Tracking Policy. | `string` | `"300"` | no |
142 | | key\_pair | Name of an existing EC2 KeyPair to enable SSH access to the instances. | `string` | `""` | no |
143 | | load\_balancer\_names | A list of Classic load balancers associated with this Auto Scaling group. | `list(string)` | `[]` | no |
144 | | metadata\_http\_endpoint | Whether the metadata service is available. Valid values include enabled or disabled. | `string` | `"enabled"` | no |
145 | | metadata\_http\_put\_response\_hop\_limit | Desired HTTP PUT response hop limit for instance metadata requests. The larger the number, the further instance metadata requests can travel. Valid values are integer from 1 to 64 | `number` | `1` | no |
146 | | metadata\_http\_tokens | Whether or not the metadata service requires session tokens, also referred to as Instance Metadata Service Version 2 (IMDSv2). Valid values include optional or required. | `string` | `"optional"` | no |
147 | | metadata\_instance\_metadata\_tags | Enables or disables access to instance tags from the instance metadata service. Valid values include enabled or disabled | `string` | `"disabled"` | no |
148 | | name | Name to be used for the provisioned EC2 instance(s), ASG(s), and other resources provisioned in this module | `string` | n/a | yes |
149 | | notification\_topic | List of SNS Topic ARNs to use for customer notifications. | `list(string)` | `[]` | no |
150 | | perform\_ssm\_inventory\_tag | Determines whether Instance is tracked via System Manager Inventory. | `string` | `"True"` | no |
151 | | policy\_type | Enter scaling policy type. Allowed values are : SimpleScaling or TargetTrackingScaling | `string` | `"SimpleScaling"` | no |
152 | | primary\_ebs\_volume\_iops | Iops value required for use with io1 EBS volumes. This value should be 3 times the EBS volume size | `string` | `"0"` | no |
153 | | primary\_ebs\_volume\_size | EBS Volume Size in GB | `string` | `"60"` | no |
154 | | primary\_ebs\_volume\_type | EBS Volume Type. e.g. gp2, io1, st1, sc1 | `string` | `"gp2"` | no |
155 | | provide\_custom\_cw\_agent\_config | Set to true if a custom cloudwatch agent configuration has been provided in variable custom\_cw\_agent\_config\_ssm\_param. | `bool` | `false` | no |
156 | | rackspace\_alarms\_enabled | Specifies whether alarms will create a Rackspace ticket. Ignored if rackspace\_managed is set to false. | `bool` | `false` | no |
157 | | rackspace\_managed | Boolean parameter controlling if instance will be fully managed by Rackspace support teams, created CloudWatch alarms that generate tickets, and utilize Rackspace managed SSM documents. | `bool` | `true` | no |
158 | | scaling\_max | The maximum size of the Auto Scaling group. | `string` | `"2"` | no |
159 | | scaling\_min | The minimum count of EC2 instances in the Auto Scaling group. | `string` | `"1"` | no |
160 | | scaling\_notification\_topic | SNS Topic ARN to notify if there are any scaling operations. OPTIONAL | `string` | `""` | no |
161 | | secondary\_ebs\_volume\_existing\_id | The Snapshot ID of an existing EBS volume you want to use for the secondary volume. i.e. snap-0ad8580e3ac34a9f1 | `string` | `""` | no |
162 | | secondary\_ebs\_volume\_iops | Iops value required for use with io1 EBS volumes. This value should be 3 times the EBS volume size | `string` | `"0"` | no |
163 | | secondary\_ebs\_volume\_size | EBS Volume Size in GB | `string` | `""` | no |
164 | | secondary\_ebs\_volume\_type | EBS Volume Type. e.g. gp2, io1, st1, sc1 | `string` | `"gp2"` | no |
165 | | security\_groups | A list of EC2 security IDs to assign to this resource. | `list(string)` | n/a | yes |
166 | | ssm\_association\_refresh\_rate | A cron or rate pattern to define the SSM Association refresh schedule, defaulting to once per day. See https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-cron.html for more details. Schedule can be disabled by providing an empty string. | `string` | `"rate(1 day)"` | no |
167 | | ssm\_bootstrap\_list | A list of objects consisting of actions, to be appended to SSM associations. Please see usage.tf.example in this repo for examples. | `any` | `[]` | no |
168 | | ssm\_patching\_group | Group ID to be used by System Manager for Patching | `string` | `""` | no |
169 | | subnets | List of subnets for Application. e.g. ['subnet-8da92df7', 'subnet-9e5dc5f6', 'subnet-497eaf33'] | `list(string)` | n/a | yes |
170 | | tags | A map of tags to apply to all resources. These tags will all be propagated to ASG instances and set on all other resources. | `map(string)` | `{}` | no |
171 | | tags\_asg | A map of tags to apply to the ASG itself. These tags will not be propagated to ASG instances or set on any other resources. | `map(string)` | `{}` | no |
172 | | target\_group\_arns | A list of Amazon Resource Names (ARN) of target groups to associate with the Auto Scaling group. | `list(string)` | `[]` | no |
173 | | target\_value | Enter the target value for Target Scaling Policy metrics. | `string` | `"50"` | no |
174 | | tenancy | The placement tenancy for EC2 devices. e.g. host, default, dedicated | `string` | `"default"` | no |
175 | | terminated\_instances | Specifies the maximum number of instances that can be terminated in a six hour period without generating a Cloudwatch Alarm. | `string` | `"30"` | no |
176 | | tracking\_policy\_metric | Allowed Values are: ASGAverageCPUUtilization, ASGAverageNetworkIn, ASGAverageNetworkOut, ALBRequestCountPerTarget | `string` | `"ASGAverageCPUUtilization"` | no |
177 |
178 | ## Outputs
179 |
180 | | Name | Description |
181 | |------|-------------|
182 | | asg\_arn\_list | List of ASG ARNs |
183 | | asg\_image\_id | Image ID used for EC2 provisioning |
184 | | asg\_name\_list | List of ASG names |
185 | | iam\_role | Name of the created IAM Instance role. |
186 |
--------------------------------------------------------------------------------
/examples/basic_usage.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 1.0.0"
3 | }
4 |
5 | provider "aws" {
6 | version = "~> 3.0"
7 | region = "us-west-2"
8 | }
9 |
10 | resource "random_string" "name_rstring" {
11 | length = 8
12 | special = false
13 | }
14 |
15 | module "vpc" {
16 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-vpc_basenetwork?ref=v0.12.7"
17 |
18 | name = "${random_string.name_rstring.result}-ec2-asg-basenetwork-example"
19 | }
20 |
21 | data "aws_region" "current_region" {}
22 |
23 | resource "random_string" "sqs_rstring" {
24 | length = 18
25 | special = false
26 | upper = false
27 | }
28 |
29 | resource "aws_sqs_queue" "ec2_asg_test_sqs" {
30 | name = "${random_string.sqs_rstring.result}-my-example-queue"
31 | }
32 |
33 | module "sns" {
34 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-sns?ref=v0.12.2"
35 |
36 | create_subscription_1 = true
37 | endpoint_1 = aws_sqs_queue.ec2_asg_test_sqs.arn
38 | name = "${random_string.sqs_rstring.result}-ec2-asg-test-topic"
39 | protocol_1 = "sqs"
40 | }
41 |
42 |
43 | module "clb" {
44 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-clb?ref=v0.12.4"
45 |
46 | name = "${random_string.name_rstring.result}-ec2-asg-clb-example"
47 | security_groups = [module.vpc.default_sg]
48 | subnets = module.vpc.public_subnets
49 | internal_loadbalancer = false
50 | create_logging_bucket = false
51 | rackspace_managed = false
52 |
53 | tags = {
54 | Example = "Example-clb"
55 | }
56 |
57 |
58 | listeners = [
59 | {
60 | instance_port = 8000
61 | instance_protocol = "HTTP"
62 | lb_port = 80
63 | lb_protocol = "HTTP"
64 | },
65 | ]
66 | }
67 |
68 | module "ec2_asg" {
69 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-ec2_asg?ref=v0.12.23"
70 |
71 | asg_count = "2"
72 | asg_wait_for_capacity_timeout = "10m"
73 | backup_tag_value = "False"
74 | cloudwatch_log_retention = "30"
75 | cw_high_evaluations = "3"
76 | cw_high_operator = "GreaterThanThreshold"
77 | cw_high_period = "60"
78 | cw_high_threshold = "60"
79 | cw_low_evaluations = "3"
80 | cw_low_operator = "LessThanThreshold"
81 | cw_low_period = "300"
82 | cw_low_threshold = "30"
83 | cw_scaling_metric = "CPUUtilization"
84 | detailed_monitoring = true
85 | ec2_os = "centos7"
86 | ec2_scale_down_adjustment = "1"
87 | ec2_scale_down_cool_down = "60"
88 | ec2_scale_up_adjustment = "1"
89 | ec2_scale_up_cool_down = "60"
90 | enable_ebs_optimization = false
91 | enable_scaling_notification = true
92 | encrypt_secondary_ebs_volume = false
93 | environment = "Development"
94 | health_check_grace_period = "300"
95 | health_check_type = "EC2"
96 | install_codedeploy_agent = false
97 | instance_role_managed_policy_arn_count = "3"
98 | instance_type = "t2.micro"
99 | load_balancer_names = [module.clb.name]
100 | name = "${random_string.name_rstring.result}-ec2-asg-instance-example"
101 | perform_ssm_inventory_tag = "True"
102 | primary_ebs_volume_iops = "0"
103 | primary_ebs_volume_size = "60"
104 | primary_ebs_volume_type = "gp2"
105 | rackspace_managed = true
106 | scaling_max = "2"
107 | scaling_min = "1"
108 | scaling_notification_topic = module.sns.topic_arn
109 | secondary_ebs_volume_iops = "0"
110 | secondary_ebs_volume_size = "60"
111 | secondary_ebs_volume_type = "gp2"
112 | security_groups = [module.vpc.default_sg]
113 | ssm_association_refresh_rate = "rate(1 day)"
114 | ssm_patching_group = "MyPatchGroup1"
115 | subnets = [element(module.vpc.public_subnets, 0), element(module.vpc.public_subnets, 1)]
116 | tenancy = "default"
117 | terminated_instances = "30"
118 |
119 |
120 | instance_role_managed_policy_arns = [
121 | "arn:aws:iam::aws:policy/AmazonEC2FullAccess",
122 | "arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole",
123 | "arn:aws:iam::aws:policy/CloudWatchActionsEC2Access",
124 | ]
125 |
126 | ssm_bootstrap_list = [
127 | {
128 | action = "aws:runDocument",
129 | inputs = {
130 | documentPath = "arn:aws:ssm:${data.aws_region.current_region.name}:507897595701:document/Rack-Install_Package",
131 | documentParameters = {
132 | Packages = "tmux"
133 | },
134 | documentType = "SSMDocument"
135 | },
136 | name = "InstallTmux",
137 | timeoutSeconds = 300
138 | },
139 | {
140 | action = "aws:runDocument",
141 | inputs = {
142 | documentPath = "AWS-RunShellScript",
143 | documentParameters = {
144 | commands = ["touch /tmp/myfile"]
145 | },
146 | documentType = "SSMDocument"
147 | },
148 | name = "CreateFile",
149 | timeoutSeconds = 300
150 | },
151 | ]
152 |
153 | tags = {
154 | MyTag1 = "Myvalue1"
155 | MyTag2 = "Myvalue2"
156 | MyTag3 = "Myvalue3"
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/examples/custom_ami.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 1.0.0"
3 | }
4 |
5 | provider "aws" {
6 | version = "~> 3.0"
7 | region = "us-west-2"
8 | }
9 |
10 | resource "random_string" "name_rstring" {
11 | length = 8
12 | special = false
13 | }
14 |
15 | module "vpc" {
16 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-vpc_basenetwork?ref=v0.12.7"
17 |
18 | name = "${random_string.name_rstring.result}-ec2-asg-basenetwork-example"
19 | }
20 |
21 | module "alb" {
22 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-alb//?ref=v0.12.10"
23 |
24 | create_logging_bucket = false
25 | http_listeners_count = 1
26 | name = "${random_string.name_rstring.result}-test-alb"
27 | rackspace_managed = false
28 | security_groups = [module.vpc.default_sg]
29 | subnets = module.vpc.public_subnets
30 | target_groups_count = 1
31 | vpc_id = module.vpc.vpc_id
32 |
33 | http_listeners = [
34 | {
35 | port = 80
36 | protocol = "HTTP"
37 | },
38 | ]
39 |
40 | target_groups = [
41 | {
42 | backend_port = 80
43 | backend_protocol = "HTTP"
44 | name = "ExampleTargetGroup"
45 | tagert_type = "alb"
46 |
47 | }
48 | ]
49 | }
50 |
51 |
52 |
53 | data "aws_region" "current_region" {}
54 |
55 | data "aws_ami" "centos7_marketplace" {
56 | owners = ["aws-marketplace"]
57 | most_recent = true
58 |
59 | filter {
60 | name = "product-code"
61 | values = ["cvugziknvmxgqna9noibqnnsy"]
62 | }
63 | }
64 |
65 | resource "random_string" "sqs_rstring" {
66 | length = 18
67 | special = false
68 | upper = false
69 | }
70 |
71 | resource "aws_sqs_queue" "ec2_asg_test_sqs" {
72 | name = "${random_string.sqs_rstring.result}-my-example-queue"
73 | }
74 |
75 | module "sns" {
76 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-sns?ref=v0.12.2"
77 |
78 | create_subscription_1 = true
79 | endpoint_1 = aws_sqs_queue.ec2_asg_test_sqs.arn
80 | name = "${random_string.sqs_rstring.result}-ec2-asg-test-topic"
81 | protocol_1 = "sqs"
82 | }
83 |
84 | module "ec2_asg" {
85 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-ec2_asg?ref=v0.12.23"
86 |
87 | asg_count = "2"
88 | asg_wait_for_capacity_timeout = "10m"
89 | backup_tag_value = "False"
90 | cloudwatch_log_retention = "30"
91 | cw_high_evaluations = "3"
92 | cw_high_operator = "GreaterThanThreshold"
93 | cw_high_period = "60"
94 | cw_high_threshold = "60"
95 | cw_low_evaluations = "3"
96 | cw_low_operator = "LessThanThreshold"
97 | cw_low_period = "300"
98 | cw_low_threshold = "30"
99 | cw_scaling_metric = "CPUUtilization"
100 | detailed_monitoring = true
101 | ec2_os = "centos7"
102 | ec2_scale_down_adjustment = "1"
103 | ec2_scale_down_cool_down = "60"
104 | ec2_scale_up_adjustment = "1"
105 | ec2_scale_up_cool_down = "60"
106 | enable_ebs_optimization = false
107 | enable_scaling_notification = true
108 | encrypt_secondary_ebs_volume = false
109 | environment = "Development"
110 | health_check_grace_period = "300"
111 | health_check_type = "EC2"
112 | image_id = data.aws_ami.centos7_marketplace.id
113 | install_codedeploy_agent = false
114 | instance_role_managed_policy_arn_count = "3"
115 | instance_type = "t2.micro"
116 | target_group_arns = module.alb.target_group_arns
117 | name = "${random_string.name_rstring.result}-ec2-asg-custom-ami-example"
118 | perform_ssm_inventory_tag = "True"
119 | primary_ebs_volume_iops = "0"
120 | primary_ebs_volume_size = "60"
121 | primary_ebs_volume_type = "gp2"
122 | rackspace_managed = true
123 | scaling_max = "2"
124 | scaling_min = "1"
125 | scaling_notification_topic = module.sns.topic_arn
126 | secondary_ebs_volume_iops = "0"
127 | secondary_ebs_volume_size = "60"
128 | secondary_ebs_volume_type = "gp2"
129 | security_groups = [module.vpc.default_sg]
130 | ssm_association_refresh_rate = "rate(1 day)"
131 | ssm_patching_group = "MyPatchGroup1"
132 | subnets = [element(module.vpc.public_subnets, 0), element(module.vpc.public_subnets, 1)]
133 | tenancy = "default"
134 | terminated_instances = "30"
135 |
136 | instance_role_managed_policy_arns = [
137 | "arn:aws:iam::aws:policy/AmazonEC2FullAccess",
138 | "arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole",
139 | "arn:aws:iam::aws:policy/CloudWatchActionsEC2Access",
140 | ]
141 |
142 |
143 | ssm_bootstrap_list = [
144 | {
145 | action = "aws:runDocument",
146 | inputs = {
147 | documentPath = "arn:aws:ssm:${data.aws_region.current_region.name}:507897595701:document/Rack-Install_Package",
148 | documentParameters = {
149 | Packages = "tmux"
150 | },
151 | documentType = "SSMDocument"
152 | },
153 | name = "InstallTmux",
154 | timeoutSeconds = 300
155 | },
156 | {
157 | action = "aws:runDocument",
158 | inputs = {
159 | documentPath = "AWS-RunShellScript",
160 | documentParameters = {
161 | commands = ["touch /tmp/myfile"]
162 | },
163 | documentType = "SSMDocument"
164 | },
165 | name = "CreateFile",
166 | timeoutSeconds = 300
167 | },
168 | ]
169 |
170 | tags = {
171 | MyTag1 = "Myvalue1"
172 | MyTag2 = "Myvalue2"
173 | MyTag3 = "Myvalue3"
174 | }
175 | }
176 |
177 |
--------------------------------------------------------------------------------
/examples/custom_cw_config.tf:
--------------------------------------------------------------------------------
1 | locals {
2 | cwagent_vars = {
3 | application_log_group_name = "custom_app_log_group_name"
4 | system_log_group_name = "custom_system_log_group_name"
5 | }
6 | }
7 |
8 | terraform {
9 | required_version = ">= 1.0.0"
10 | }
11 |
12 | provider "aws" {
13 | version = "~> 3.0"
14 | region = "us-west-2"
15 | }
16 |
17 | resource "random_string" "name_rstring" {
18 | length = 8
19 | special = false
20 | }
21 |
22 |
23 | module "vpc" {
24 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-vpc_basenetwork?ref=v0.12.7"
25 |
26 | name = "${random_string.name_rstring.result}-ec2-asg-basenetwork-example"
27 | }
28 |
29 | data "aws_region" "current_region" {}
30 |
31 | resource "random_string" "sqs_rstring" {
32 | length = 18
33 | special = false
34 | upper = false
35 | }
36 |
37 | resource "aws_sqs_queue" "ec2_asg_test_sqs" {
38 | name = "${random_string.sqs_rstring.result}-my-example-queue"
39 | }
40 |
41 | module "sns" {
42 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-sns?ref=v0.12.2"
43 |
44 | create_subscription_1 = true
45 | endpoint_1 = aws_sqs_queue.ec2_asg_test_sqs.arn
46 | name = "${random_string.sqs_rstring.result}-ec2-asg-test-topic"
47 | protocol_1 = "sqs"
48 | }
49 |
50 |
51 | module "clb" {
52 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-clb?ref=v0.12.4"
53 |
54 | name = "${random_string.name_rstring.result}-ec2-asg-clb-example"
55 | security_groups = [module.vpc.default_sg]
56 | subnets = module.vpc.public_subnets
57 | internal_loadbalancer = false
58 | create_logging_bucket = false
59 | rackspace_managed = false
60 |
61 | tags = {
62 | Example = "Example-clb"
63 | }
64 |
65 |
66 | listeners = [
67 | {
68 | instance_port = 8000
69 | instance_protocol = "HTTP"
70 | lb_port = 80
71 | lb_protocol = "HTTP"
72 | },
73 | ]
74 | }
75 |
76 | module "ec2_asg" {
77 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-ec2_asg?ref=v0.12.23"
78 |
79 | asg_count = "2"
80 | asg_wait_for_capacity_timeout = "10m"
81 | backup_tag_value = "False"
82 | cloudwatch_log_retention = "30"
83 | custom_cw_agent_config_ssm_param = aws_ssm_parameter.custom_cwagentparam.name
84 | cw_high_evaluations = "3"
85 | cw_high_operator = "GreaterThanThreshold"
86 | cw_high_period = "60"
87 | cw_high_threshold = "60"
88 | cw_low_evaluations = "3"
89 | cw_low_operator = "LessThanThreshold"
90 | cw_low_period = "300"
91 | cw_low_threshold = "30"
92 | cw_scaling_metric = "CPUUtilization"
93 | detailed_monitoring = true
94 | ec2_os = "centos7"
95 | ec2_scale_down_adjustment = "1"
96 | ec2_scale_down_cool_down = "60"
97 | ec2_scale_up_adjustment = "1"
98 | ec2_scale_up_cool_down = "60"
99 | enable_ebs_optimization = false
100 | enable_scaling_notification = true
101 | encrypt_secondary_ebs_volume = false
102 | environment = "Development"
103 | health_check_grace_period = "300"
104 | health_check_type = "EC2"
105 | install_codedeploy_agent = false
106 | instance_role_managed_policy_arn_count = "2"
107 | instance_type = "t2.micro"
108 | load_balancer_names = [module.clb.name]
109 | name = "${random_string.name_rstring.result}-ec2-asg-instance-example"
110 | perform_ssm_inventory_tag = "True"
111 | primary_ebs_volume_iops = "0"
112 | primary_ebs_volume_size = "60"
113 | primary_ebs_volume_type = "gp2"
114 | provide_custom_cw_agent_config = true
115 | rackspace_managed = true
116 | scaling_max = "2"
117 | scaling_min = "1"
118 | scaling_notification_topic = module.sns.topic_arn
119 | secondary_ebs_volume_iops = "0"
120 | secondary_ebs_volume_size = "60"
121 | secondary_ebs_volume_type = "gp2"
122 | security_groups = [module.vpc.default_sg]
123 | ssm_association_refresh_rate = "rate(1 day)"
124 | ssm_patching_group = "MyPatchGroup1"
125 | subnets = [element(module.vpc.public_subnets, 0), element(module.vpc.public_subnets, 1)]
126 | tenancy = "default"
127 | terminated_instances = "30"
128 |
129 | instance_role_managed_policy_arns = [
130 | "arn:aws:iam::aws:policy/AmazonEC2FullAccess",
131 | "arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole",
132 | "arn:aws:iam::aws:policy/CloudWatchActionsEC2Access",
133 | ]
134 |
135 | ssm_bootstrap_list = [
136 | {
137 | action = "aws:runDocument",
138 | inputs = {
139 | documentPath = "arn:aws:ssm:${data.aws_region.current_region.name}:507897595701:document/Rack-Install_Package",
140 | documentParameters = {
141 | Packages = "tmux"
142 | },
143 | documentType = "SSMDocument"
144 | },
145 | name = "InstallTmux",
146 | timeoutSeconds = 300
147 | },
148 | {
149 | action = "aws:runDocument",
150 | inputs = {
151 | documentPath = "AWS-RunShellScript",
152 | documentParameters = {
153 | commands = ["touch /tmp/myfile"]
154 | },
155 | documentType = "SSMDocument"
156 | },
157 | name = "CreateFile",
158 | timeoutSeconds = 300
159 | },
160 | ]
161 |
162 | tags = {
163 | MyTag1 = "Myvalue1"
164 | MyTag2 = "Myvalue2"
165 | MyTag3 = "Myvalue3"
166 | }
167 | }
168 |
169 | resource "random_string" "res_name" {
170 | length = 8
171 | lower = true
172 | number = false
173 | special = false
174 | upper = false
175 | }
176 |
177 | resource "aws_ssm_parameter" "custom_cwagentparam" {
178 | description = "Custom Cloudwatch Agent configuration"
179 | name = "custom_cw_param-${random_string.res_name.result}"
180 | type = "String"
181 | value = templatefile("./text/linux_cw_agent_param.json", local.cwagent_vars)
182 | }
--------------------------------------------------------------------------------
/examples/text/linux_cw_agent_param.json:
--------------------------------------------------------------------------------
1 | {"metrics":{"append_dimensions":{"InstanceId":"$${aws:InstanceId}","AutoScalingGroupName":"$${aws:AutoScalingGroupName}"},"aggregation_dimensions":[["InstanceId"],["AutoScalingGroupName"],["InstanceId","device"]],"namespace":"System/Linux","metrics_collected":{"mem":{"metrics_collection_interval":60,"measurement":[{"rename":"MemoryUtilization","name":"mem_used_percent","unit":"Percent"}]},"disk":{"ignore_file_system_types":["devtmpfs","tmpfs","devfs","rootfs"],"metrics_collection_interval":60,"resources":["*"],"measurement":["used_percent"]}}},"logs":{"logs_collected":{"files":{"collect_list":[{"file_path":"/var/log/cloud-init-output.log","log_group_name":"${system_log_group_name}","log_stream_name":"{instance_id}/cloud-init-output.log"},{"timestamp_format":"%b %d %H:%M:%S","file_path":"/var/log/cloud-init.log","log_group_name":"${system_log_group_name}","log_stream_name":"{instance_id}/cloud-init.log"},{"timestamp_format":"%Y-%m-%d %H:%M:%S","multi_line_start_pattern":"{timestamp_format}","file_path":"/var/log/amazon/ssm/amazon-ssm-agent.log","log_group_name":"${system_log_group_name}","log_stream_name":"{instance_id}/amazon-ssm-agent.log"},{"timestamp_format":"%Y-%m-%d %H:%M:%S","multi_line_start_pattern":"{timestamp_format}","file_path":"/var/log/amazon/ssm/errors.log","log_group_name":"${system_log_group_name}","log_stream_name":"{instance_id}/amazon-ssm-errors.log"},{"timestamp_format":"%d/%b/%Y:%H:%M:%S","file_path":"/var/log/httpd/access*","log_group_name":"${application_log_group_name}","log_stream_name":"{instance_id}/httpd-access"},{"timestamp_format":"%d/%b/%Y:%H:%M:%S","file_path":"/var/log/httpd/error*","log_group_name":"${application_log_group_name}","log_stream_name":"{instance_id}/httpd-error"},{"timestamp_format":"%d/%b/%Y:%H:%M:%S","file_path":"/var/log/apache2/access*","log_group_name":"${application_log_group_name}","log_stream_name":"{instance_id}/apache2-access"},{"timestamp_format":"%d/%b/%Y:%H:%M:%S","file_path":"/var/log/apache2/error*","log_group_name":"${application_log_group_name}","log_stream_name":"{instance_id}/apache2-error"},{"timestamp_format":"%d/%b/%Y:%H:%M:%S","file_path":"/var/log/nginx/access*","log_group_name":"${application_log_group_name}","log_stream_name":"{instance_id}/nginx-access"},{"timestamp_format":"%d/%b/%Y:%H:%M:%S","file_path":"/var/log/nginx/error*","log_group_name":"${application_log_group_name}","log_stream_name":"{instance_id}/nginx-error"},{"timestamp_format":"%a %b %d %H:%M:%S","file_path":"/etc/openvpn/openvpn.log*","log_group_name":"${application_log_group_name}","log_stream_name":"{instance_id}/openvpn.log"}]}}}}
--------------------------------------------------------------------------------
/main.tf:
--------------------------------------------------------------------------------
1 | /**
2 | * # aws-terraform-ec2_asg
3 | *
4 | * This module creates one or more autoscaling groups.
5 | *
6 | * ## Basic Usage
7 | *
8 | * ```HCL
9 | * module "asg" {
10 | * source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-ec2_asg//?ref=v0.12.16"
11 | *
12 | * ec2_os = "amazon2"
13 | * name = "my_asg"
14 | * security_groups = [module.sg.private_web_security_group_id]
15 | * subnets = module.vpc.private_subnets
16 | * }
17 | * ```
18 | *
19 | * Full working references are available at [examples](examples)
20 | *
21 | * ## Other TF Modules Used
22 | *
23 | * Using [aws-terraform-cloudwatch_alarm](https://github.com/rackspace-infrastructure-automation/aws-terraform-cloudwatch_alarm) to create the following CloudWatch Alarms:
24 | * - group_terminating_instances
25 | *
26 | * ## Terraform 0.12 upgrade
27 | *
28 | * Several changes were required while adding terraform 0.12 compatibility. The following changes should
29 | * made when upgrading from a previous release to version 0.12.0 or higher.
30 | *
31 | * ### Module variables
32 | *
33 | * The following module variables were updated to better meet current Rackspace style guides:
34 | *
35 | * - `security_group_list` -> `security_groups`
36 | * - `resource_name` -> `name`
37 | *
38 | * The following variables are no longer neccessary and were removed
39 | *
40 | * - `additional_ssm_bootstrap_step_count`
41 | * - `install_scaleft_agent`
42 | *
43 | * Several new variables were introduced to provide existing functionality, with a simplified format. The original formmating was also retained to allow easier transition.
44 | *
45 | * New variables `tags` and `tags_asg` were added to replace the functionality of the `additional_tags` variable. `tags` allows setting tags on all resources, while `tags_asg` sets tags only on the ASG itself. `additional_tags` will continue to work as expected, but will be removed in a future release.
46 | *
47 | * New variable `ssm_bootstrap_list` was added to allow setting the SSM association steps using objects instead of strings, allowing easier linting and formatting of these lines. The `additional_ssm_bootstrap_list` variable will continue to work, but will be deprecated in a future release.
48 | */
49 |
50 | locals {
51 | user_data_vars = {
52 | initial_commands = var.initial_userdata_commands
53 | final_commands = var.final_userdata_commands
54 | }
55 | }
56 |
57 | terraform {
58 | required_version = ">= 1.0.0"
59 |
60 | required_providers {
61 | aws = "~> 3.0"
62 | }
63 | }
64 |
65 | locals {
66 | ec2_os = lower(var.ec2_os)
67 |
68 | ec2_os_windows_length_test = length(local.ec2_os) >= 7 ? 7 : length(local.ec2_os)
69 | ec2_os_windows = substr(local.ec2_os, 0, local.ec2_os_windows_length_test) == "windows" ? true : false
70 |
71 | # Enforce metrics needed for CW
72 | asg_metrics = distinct(concat(var.enabled_asg_metrics, ["GroupTerminatingInstances"]))
73 |
74 | cw_config_parameter_name = "CWAgent-${var.name}"
75 |
76 | ssm_doc_content = {
77 | schemaVersion = "2.2"
78 | description = "SSM Document for instance configuration."
79 | parameters = {}
80 | mainSteps = local.ssm_command_list
81 | }
82 |
83 | ssm_command_list = concat(
84 | local.default_ssm_cmd_list,
85 | local.ssm_codedeploy_include[var.install_codedeploy_agent],
86 | [for s in var.additional_ssm_bootstrap_list : jsondecode(s.ssm_add_step)],
87 | var.ssm_bootstrap_list,
88 | )
89 |
90 | # This is a list of ssm main steps
91 | default_ssm_cmd_list = [
92 | {
93 | action = "aws:runDocument"
94 | name = "BusyWait"
95 | timeoutSeconds = 300
96 |
97 | inputs = {
98 | documentPath = "AWS-RunDocument"
99 | documentType = "SSMDocument"
100 |
101 | documentParameters = {
102 | documentParameters = {}
103 | sourceInfo = "{\"path\": \"https://rackspace-ssm-docs-${data.aws_region.current_region.name}.s3.amazonaws.com/latest/configuration/Rack-BusyWait.json\"}"
104 | sourceType = "S3"
105 | }
106 | }
107 | },
108 | {
109 | action = "aws:runDocument"
110 | name = "InstallCWAgent"
111 | timeoutSeconds = 300
112 |
113 | inputs = {
114 | documentPath = "AWS-ConfigureAWSPackage"
115 | documentType = "SSMDocument"
116 |
117 | documentParameters = {
118 | action = "Install"
119 | name = "AmazonCloudWatchAgent"
120 | }
121 | }
122 | },
123 | {
124 | action = "aws:runDocument"
125 | name = "ConfigureCWAgent"
126 | timeoutSeconds = 300
127 |
128 | inputs = {
129 | documentPath = "AmazonCloudWatch-ManageAgent"
130 | documentType = "SSMDocument"
131 |
132 | documentParameters = {
133 | action = "configure"
134 | name = "AmazonCloudWatchAgent"
135 | optionalConfigurationLocation = var.provide_custom_cw_agent_config ? var.custom_cw_agent_config_ssm_param : local.cw_config_parameter_name
136 | optionalConfigurationSource = "ssm"
137 | optionalRestart = "yes"
138 | }
139 | }
140 | },
141 | {
142 | action = "aws:runDocument"
143 | name = "SetupTimeSync"
144 | timeoutSeconds = 300
145 |
146 | inputs = {
147 | documentPath = "AWS-RunDocument"
148 | documentType = "SSMDocument"
149 |
150 | documentParameters = {
151 | documentParameters = {}
152 | sourceInfo = "{\"path\": \"https://rackspace-ssm-docs-${data.aws_region.current_region.name}.s3.amazonaws.com/latest/configuration/Rack-ConfigureAWSTimeSync.json\"}"
153 | sourceType = "S3"
154 | }
155 | }
156 | },
157 | {
158 | action = "aws:runDocument"
159 | name = "DiagnosticTools"
160 | timeoutSeconds = 300
161 |
162 | inputs = {
163 | documentPath = "AWS-RunDocument"
164 | documentType = "SSMDocument"
165 |
166 | documentParameters = {
167 | documentParameters = { Packages = lookup(local.diagnostic_packages, local.ec2_os, "") }
168 | sourceInfo = "{\"path\": \"https://rackspace-ssm-docs-${data.aws_region.current_region.name}.s3.amazonaws.com/latest/configuration/Rack-Install_Package.json\"}"
169 | sourceType = "S3"
170 | }
171 | }
172 | },
173 | {
174 | action = "aws:runDocument"
175 | name = "SetMotd"
176 | timeoutSeconds = 300
177 |
178 | inputs = {
179 | documentPath = "AWS-RunDocument"
180 | documentType = "SSMDocument"
181 |
182 | documentParameters = {
183 | documentParameters = {}
184 | sourceInfo = "{\"path\": \"https://rackspace-ssm-docs-${data.aws_region.current_region.name}.s3.amazonaws.com/latest/configuration/Rack-SetMotd.json\"}"
185 | sourceType = "S3"
186 | }
187 | }
188 | },
189 | ]
190 |
191 | ssm_codedeploy_include = {
192 | true = [
193 | {
194 | action = "aws:runDocument"
195 | name = "InstallCodeDeployAgent"
196 | timeoutSeconds = 300
197 |
198 | inputs = {
199 | documentPath = "AWS-RunDocument"
200 | documentType = "SSMDocument"
201 |
202 | documentParameters = {
203 | documentParameters = {}
204 | sourceInfo = "{\"path\": \"https://rackspace-ssm-docs-${data.aws_region.current_region.name}.s3.amazonaws.com/latest/configuration/Rack-Install_CodeDeploy.json\"}"
205 | sourceType = "S3"
206 | }
207 | }
208 | },
209 | ]
210 |
211 | false = []
212 | }
213 |
214 | defaults = {
215 | diagnostic_packages = {
216 | amazon = "sysstat ltrace strace iptraf tcpdump"
217 | rhel = "sysstat ltrace strace lsof iotop iptraf-ng tcpdump"
218 | ubuntu = "sysstat iotop iptraf-ng"
219 | debian = "sysstat iotop iptraf-ng"
220 | }
221 | }
222 |
223 | diagnostic_packages = {
224 | amazon2 = local.defaults["diagnostic_packages"]["amazon"]
225 | amazon2023 = local.defaults["diagnostic_packages"]["amazon"]
226 | amazoneks = local.defaults["diagnostic_packages"]["amazon"]
227 | amazonecs = local.defaults["diagnostic_packages"]["amazon"]
228 | rhel7 = local.defaults["diagnostic_packages"]["rhel"]
229 | rhel8 = local.defaults["diagnostic_packages"]["rhel"]
230 | centos7 = local.defaults["diagnostic_packages"]["rhel"]
231 | ubuntu18 = local.defaults["diagnostic_packages"]["ubuntu"]
232 | ubuntu20 = local.defaults["diagnostic_packages"]["ubuntu"]
233 | debian10 = local.defaults["diagnostic_packages"]["debian"]
234 | debian11 = local.defaults["diagnostic_packages"]["debian"]
235 | }
236 |
237 | ebs_device_map = {
238 | amazon2 = "/dev/sdf"
239 | amazon2023 = "/dev/sdf"
240 | amazoneks = "/dev/sdf"
241 | amazonecs = "/dev/xvdcz"
242 | rhel7 = "/dev/sdf"
243 | rhel8 = "/dev/sdf"
244 | centos7 = "/dev/sdf"
245 | ubuntu18 = "/dev/sdf"
246 | ubuntu20 = "/dev/sdf"
247 | debian10 = "/dev/sdf"
248 | debian11 = "/dev/sdf"
249 | windows2016 = "xvdf"
250 | windows2019 = "xvdf"
251 | windows2022 = "xvdf"
252 | }
253 |
254 | root_device_map = {
255 | amazon2 = "/dev/xvda"
256 | amazon2023 = "/dev/xvda"
257 | amazoneks = "/dev/xvda"
258 | amazonecs = "/dev/xvda"
259 | rhel7 = "/dev/sda1"
260 | rhel8 = "/dev/sda1"
261 | centos7 = "/dev/sda1"
262 | ubuntu18 = "/dev/sda1"
263 | ubuntu20 = "/dev/sda1"
264 | windows2016 = "/dev/sda1"
265 | windows2019 = "/dev/sda1"
266 | windows2022 = "/dev/sda1"
267 | debian10 = "/dev/sda1"
268 | debian11 = "/dev/sda1"
269 | }
270 |
271 | cwagent_config = local.ec2_os_windows ? "windows_cw_agent_param.json" : "linux_cw_agent_param.json"
272 |
273 | # local.tags can and should be applied to all taggable resources
274 |
275 | tags = {
276 | Environment = var.environment
277 | ServiceProvider = "Rackspace"
278 | }
279 |
280 | # local.tags_ec2 is applied to the ASG and propagated to all instances
281 |
282 | tags_ec2 = {
283 | Backup = var.backup_tag_value
284 | Name = var.name
285 | "Patch Group" = var.ssm_patching_group
286 | SSMInventory = var.perform_ssm_inventory_tag
287 | "SSM Target Tag" = "Target-${var.name}"
288 | }
289 |
290 | # local.tags_asg is applied to the ASG but not propagated to the EC2 instances
291 |
292 | tags_asg = {
293 | InstanceReplacement = var.enable_rolling_updates ? "True" : "False"
294 | }
295 |
296 | user_data_map = {
297 | amazon2 = "amazon_linux_userdata.sh"
298 | amazon2023 = "amazon_linux_userdata.sh"
299 | amazonecs = "amazon_linux_userdata.sh"
300 | amazoneks = "amazon_linux_userdata.sh"
301 | rhel7 = "rhel_centos_7_userdata.sh"
302 | rhel8 = "rhel_centos_8_userdata.sh"
303 | centos7 = "rhel_centos_7_userdata.sh"
304 | ubuntu18 = "ubuntu_userdata.sh"
305 | ubuntu20 = "ubuntu_userdata.sh"
306 | debian10 = "debian_userdata.sh"
307 | debian11 = "debian_userdata.sh"
308 | windows2016 = "windows_userdata.ps1"
309 | windows2019 = "windows_userdata.ps1"
310 | windows2022 = "windows_userdata.ps1"
311 | }
312 |
313 | ami_owner_mapping = {
314 | amazon2 = "137112412989"
315 | amazon2023 = "137112412989"
316 | amazonecs = "591542846629"
317 | amazoneks = "602401143452"
318 | centos7 = "125523088429"
319 | rhel7 = "309956199498"
320 | rhel8 = "309956199498"
321 | ubuntu18 = "099720109477"
322 | ubuntu20 = "099720109477"
323 | debian10 = "136693071363"
324 | debian11 = "136693071363"
325 | windows2016 = "801119661308"
326 | windows2019 = "801119661308"
327 | windows2022 = "801119661308"
328 | }
329 |
330 | ami_name_mapping = {
331 | amazon2 = "amzn2-ami-hvm-2.0.*-ebs"
332 | amazon2023 = "al2023-ami-2023*-kernel-*-x86_64"
333 | amazonecs = "amzn2-ami-ecs-hvm-2*-x86_64-ebs"
334 | amazoneks = "amazon-eks-node-*"
335 | centos7 = "CentOS Linux 7 x86_64*"
336 | rhel7 = "RHEL-7.*_HVM-*x86_64*"
337 | rhel8 = "RHEL-8.*_HVM-*x86_64*"
338 | debian10 = "debian-10-amd64-*"
339 | debian11 = "debian-11-amd64-*"
340 | ubuntu18 = "ubuntu/images/hvm-ssd/*ubuntu-bionic-18.04-amd64-server*"
341 | ubuntu20 = "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"
342 | windows2016 = "Windows_Server-2016-English-Full-Base*"
343 | windows2019 = "Windows_Server-2019-English-Full-Base*"
344 | windows2022 = "Windows_Server-2022-English-Full-Base*"
345 | }
346 |
347 | # Any custom AMI filters for a given OS can be added in this mapping
348 | image_filter = {
349 | amazon2 = []
350 | amazon2023 = []
351 | amazonecs = []
352 | amazoneks = []
353 | centos7 = []
354 | rhel7 = []
355 | rhel8 = []
356 | ubuntu18 = []
357 | ubuntu20 = []
358 | debian10 = []
359 | debian11 = []
360 | windows2016 = []
361 | windows2019 = []
362 | windows2022 = []
363 | }
364 |
365 | standard_filters = [
366 | {
367 | name = "virtualization-type"
368 | values = ["hvm"]
369 | },
370 | {
371 | name = "root-device-type"
372 | values = ["ebs"]
373 | },
374 | {
375 | name = "name"
376 | values = [local.ami_name_mapping[local.ec2_os]]
377 | },
378 | ]
379 | }
380 |
381 | # Lookup the correct AMI based on the region specified
382 | data "aws_ami" "asg_ami" {
383 | most_recent = true
384 | owners = [local.ami_owner_mapping[local.ec2_os]]
385 |
386 | dynamic "filter" {
387 | for_each = concat(local.standard_filters, local.image_filter[local.ec2_os])
388 | content {
389 | name = filter.value.name
390 | values = filter.value.values
391 | }
392 | }
393 | }
394 |
395 | data "aws_region" "current_region" {}
396 |
397 | data "aws_caller_identity" "current_account" {}
398 |
399 | #
400 | # IAM policies
401 | #
402 |
403 | data "aws_iam_policy_document" "mod_ec2_assume_role_policy_doc" {
404 | statement {
405 | actions = ["sts:AssumeRole"]
406 | effect = "Allow"
407 |
408 | principals {
409 | identifiers = ["ec2.amazonaws.com"]
410 | type = "Service"
411 | }
412 | }
413 | }
414 |
415 | data "aws_iam_policy_document" "mod_ec2_instance_role_policies" {
416 |
417 | statement {
418 | effect = "Allow"
419 | resources = ["*"]
420 |
421 | actions = [
422 | "ssm:CreateAssociation",
423 | "ssm:DescribeInstanceInformation",
424 | "ssm:GetParameter",
425 | ]
426 | }
427 |
428 | statement {
429 | effect = "Allow"
430 | resources = ["*"]
431 |
432 | actions = [
433 | "cloudwatch:GetMetricStatistics",
434 | "cloudwatch:ListMetrics",
435 | "cloudwatch:PutMetricData",
436 | "ec2:DescribeTags",
437 | "logs:CreateLogGroup",
438 | "logs:CreateLogStream",
439 | "logs:DescribeLogStreams",
440 | "logs:PutLogEvents",
441 | ]
442 | }
443 |
444 | statement {
445 | effect = "Allow"
446 | resources = ["arn:aws:s3:::rackspace-*/*"]
447 |
448 | actions = [
449 | "s3:AbortMultipartUpload",
450 | "s3:GetBucketLocation",
451 | "s3:GetEncryptionConfiguration",
452 | "s3:GetObject",
453 | "s3:ListBucket",
454 | "s3:ListBucketMultipartUploads",
455 | "s3:ListMultipartUploadParts",
456 | "s3:PutObject",
457 | ]
458 | }
459 | }
460 |
461 | resource "aws_iam_policy" "create_instance_role_policy" {
462 | count = var.instance_profile_override ? 0 : 1
463 |
464 | description = "Rackspace Instance Role Policies for EC2"
465 | name = "InstanceRolePolicy-${var.name}"
466 | policy = data.aws_iam_policy_document.mod_ec2_instance_role_policies.json
467 | }
468 |
469 | resource "aws_iam_role" "mod_ec2_instance_role" {
470 | count = var.instance_profile_override ? 0 : 1
471 |
472 | assume_role_policy = data.aws_iam_policy_document.mod_ec2_assume_role_policy_doc.json
473 | name = "InstanceRole-${var.name}"
474 | path = "/"
475 | }
476 |
477 | resource "aws_iam_role_policy_attachment" "attach_core_ssm_policy" {
478 | count = var.instance_profile_override ? 0 : 1
479 |
480 | policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
481 | role = aws_iam_role.mod_ec2_instance_role[0].name
482 | }
483 |
484 | resource "aws_iam_role_policy_attachment" "attach_cw_ssm_policy" {
485 | count = var.instance_profile_override ? 0 : 1
486 |
487 | policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
488 | role = aws_iam_role.mod_ec2_instance_role[0].name
489 | }
490 |
491 | resource "aws_iam_role_policy_attachment" "attach_ad_ssm_policy" {
492 | count = var.instance_profile_override ? 0 : 1
493 |
494 | policy_arn = "arn:aws:iam::aws:policy/AmazonSSMDirectoryServiceAccess"
495 | role = aws_iam_role.mod_ec2_instance_role[0].name
496 | }
497 |
498 | resource "aws_iam_role_policy_attachment" "attach_codedeploy_policy" {
499 | count = var.install_codedeploy_agent && var.instance_profile_override != true ? 1 : 0
500 |
501 | policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforAWSCodeDeploy"
502 | role = aws_iam_role.mod_ec2_instance_role[0].name
503 | }
504 |
505 | resource "aws_iam_role_policy_attachment" "attach_instance_role_policy" {
506 | count = var.instance_profile_override ? 0 : 1
507 |
508 | policy_arn = aws_iam_policy.create_instance_role_policy[0].arn
509 | role = aws_iam_role.mod_ec2_instance_role[0].name
510 | }
511 |
512 | resource "aws_iam_role_policy_attachment" "attach_additonal_policies" {
513 | count = var.instance_profile_override ? 0 : var.instance_role_managed_policy_arn_count
514 |
515 | policy_arn = element(var.instance_role_managed_policy_arns, count.index)
516 | role = aws_iam_role.mod_ec2_instance_role[0].name
517 | }
518 |
519 | resource "aws_iam_instance_profile" "instance_role_instance_profile" {
520 | count = var.instance_profile_override ? 0 : 1
521 |
522 | name = "InstanceRoleInstanceProfile-${var.name}"
523 | path = "/"
524 | role = aws_iam_role.mod_ec2_instance_role[0].name
525 | }
526 |
527 | #
528 | # Provisioning of ASG related resources
529 | #
530 |
531 | resource "aws_launch_template" "launch_template_with_secondary_ebs" {
532 | count = var.secondary_ebs_volume_size != "" ? 1 : 0
533 |
534 | ebs_optimized = var.enable_ebs_optimization
535 | image_id = var.image_id != "" ? var.image_id : data.aws_ami.asg_ami.image_id
536 | instance_type = var.instance_type
537 | key_name = var.key_pair
538 | name_prefix = join("-", compact(["LaunchConfigWith2ndEbs", var.name, format("%03d-", count.index + 1)]))
539 | vpc_security_group_ids = var.security_groups
540 | user_data = base64encode(templatefile("${path.module}/text/${local.user_data_map[local.ec2_os]}", local.user_data_vars))
541 |
542 | # Root block device
543 | block_device_mappings {
544 | device_name = local.root_device_map[local.ec2_os]
545 | ebs {
546 | iops = var.primary_ebs_volume_type == "io1" ? var.primary_ebs_volume_size : 0
547 | volume_size = var.primary_ebs_volume_size
548 | volume_type = var.primary_ebs_volume_type
549 | encrypted = var.encrypt_primary_ebs_volume
550 | }
551 | }
552 | block_device_mappings {
553 | device_name = local.ebs_device_map[local.ec2_os]
554 | ebs {
555 | encrypted = var.secondary_ebs_volume_existing_id == "" ? var.encrypt_secondary_ebs_volume : false
556 | iops = var.secondary_ebs_volume_iops
557 | snapshot_id = var.secondary_ebs_volume_existing_id
558 | volume_size = var.secondary_ebs_volume_size
559 | volume_type = var.secondary_ebs_volume_type
560 | }
561 | }
562 | iam_instance_profile {
563 | name = element(
564 | coalescelist(aws_iam_instance_profile.instance_role_instance_profile.*.name,
565 | [var.instance_profile_override_name],
566 | ),
567 | 0,
568 | )
569 | }
570 | lifecycle {
571 | create_before_destroy = true
572 | }
573 | monitoring {
574 | enabled = var.detailed_monitoring
575 | }
576 | placement {
577 | tenancy = var.tenancy
578 | }
579 | metadata_options {
580 | http_endpoint = var.metadata_http_endpoint
581 | http_put_response_hop_limit = var.metadata_http_put_response_hop_limit
582 | http_tokens = var.metadata_http_tokens
583 | instance_metadata_tags = var.metadata_instance_metadata_tags
584 | }
585 | }
586 |
587 |
588 | resource "aws_launch_template" "launch_template_with_no_secondary_ebs" {
589 | count = var.secondary_ebs_volume_size != "" ? 0 : 1
590 |
591 | ebs_optimized = var.enable_ebs_optimization
592 | image_id = var.image_id != "" ? var.image_id : data.aws_ami.asg_ami.image_id
593 | instance_type = var.instance_type
594 | key_name = var.key_pair
595 | name_prefix = join("-", compact(["LaunchConfigWith2ndEbs", var.name, format("%03d-", count.index + 1)]))
596 | vpc_security_group_ids = var.security_groups
597 | user_data = base64encode(templatefile("${path.module}/text/${local.user_data_map[local.ec2_os]}", local.user_data_vars))
598 |
599 | # Root block device
600 | block_device_mappings {
601 | device_name = local.root_device_map[local.ec2_os]
602 | ebs {
603 | iops = var.primary_ebs_volume_type == "io1" ? var.primary_ebs_volume_size : 0
604 | volume_size = var.primary_ebs_volume_size
605 | volume_type = var.primary_ebs_volume_type
606 | encrypted = var.encrypt_primary_ebs_volume
607 | }
608 | }
609 | iam_instance_profile {
610 | name = element(
611 | coalescelist(aws_iam_instance_profile.instance_role_instance_profile.*.name,
612 | [var.instance_profile_override_name],
613 | ),
614 | 0,
615 | )
616 | }
617 | lifecycle {
618 | create_before_destroy = true
619 | }
620 | monitoring {
621 | enabled = var.detailed_monitoring
622 | }
623 | placement {
624 | tenancy = var.tenancy
625 | }
626 | metadata_options {
627 | http_endpoint = var.metadata_http_endpoint
628 | http_put_response_hop_limit = var.metadata_http_put_response_hop_limit
629 | http_tokens = var.metadata_http_tokens
630 | instance_metadata_tags = var.metadata_instance_metadata_tags
631 | }
632 | }
633 |
634 | resource "aws_autoscaling_policy" "ec2_scale_up_policy" {
635 | count = var.policy_type == "SimpleScaling" && var.enable_scaling_actions == true ? var.asg_count : 0
636 |
637 | adjustment_type = "ChangeInCapacity"
638 | autoscaling_group_name = element(aws_autoscaling_group.autoscalegrp.*.name, count.index)
639 | cooldown = var.ec2_scale_up_cool_down
640 | name = join("-", compact(["ec2_scale_up_policy", var.name, format("%03d", count.index + 1)]))
641 | scaling_adjustment = var.ec2_scale_up_adjustment
642 | }
643 |
644 | resource "aws_autoscaling_policy" "ec2_scale_down_policy" {
645 | count = var.policy_type == "SimpleScaling" && var.enable_scaling_actions == true ? var.asg_count : 0
646 |
647 | adjustment_type = "ChangeInCapacity"
648 | autoscaling_group_name = element(aws_autoscaling_group.autoscalegrp.*.name, count.index)
649 | cooldown = var.ec2_scale_down_cool_down
650 | name = join("-", compact(["ec2_scale_down_policy", var.name, format("%03d", count.index + 1)]))
651 | scaling_adjustment = var.ec2_scale_down_adjustment > 0 ? -var.ec2_scale_down_adjustment : var.ec2_scale_down_adjustment
652 | }
653 |
654 | resource "aws_autoscaling_policy" "ec2_scale_up_down_target_tracking" {
655 | count = var.policy_type == "TargetTrackingScaling" ? var.asg_count : 0
656 |
657 | name = join("-", compact(["ec2_scale_up_down_target_tracking_policy", var.name, format("%03d", count.index + 1)]))
658 | autoscaling_group_name = element(aws_autoscaling_group.autoscalegrp.*.name, count.index)
659 | estimated_instance_warmup = var.instance_warm_up_time
660 | policy_type = var.policy_type
661 | target_tracking_configuration {
662 | predefined_metric_specification {
663 | predefined_metric_type = var.tracking_policy_metric
664 | resource_label = var.alb_resource_label
665 | }
666 | target_value = var.target_value
667 | disable_scale_in = var.disable_scale_in
668 | }
669 | }
670 |
671 | resource "aws_autoscaling_group" "autoscalegrp" {
672 | count = var.asg_count
673 |
674 | enabled_metrics = local.asg_metrics
675 | health_check_grace_period = var.health_check_grace_period
676 | health_check_type = var.health_check_type
677 | load_balancers = var.load_balancer_names
678 | max_size = var.scaling_max
679 | metrics_granularity = "1Minute"
680 | min_size = var.scaling_min
681 | name_prefix = join("-", compact(["AutoScaleGrp", var.name, format("%03d-", count.index + 1)]))
682 | target_group_arns = var.target_group_arns
683 | vpc_zone_identifier = var.subnets
684 | wait_for_capacity_timeout = var.asg_wait_for_capacity_timeout
685 |
686 | launch_template {
687 | id = element(coalescelist(
688 | aws_launch_template.launch_template_with_secondary_ebs.*.id,
689 | aws_launch_template.launch_template_with_no_secondary_ebs.*.id, ),
690 | count.index)
691 | version = "$Latest"
692 | }
693 |
694 | # This block sets tags provided as objects, allowing the propagate at launch field to be set to False
695 | dynamic "tag" {
696 | for_each = var.additional_tags
697 |
698 | content {
699 | key = tag.value.key
700 | value = tag.value.value
701 | propagate_at_launch = lookup(tag.value, "propagate_at_launch", true)
702 | }
703 | }
704 |
705 | # This block sets tags provided as a map in the tags variable (propagated to ASG instances).
706 | dynamic "tag" {
707 | for_each = merge(var.tags, local.tags_ec2, local.tags)
708 |
709 | content {
710 | key = tag.key
711 | value = tag.value
712 | propagate_at_launch = true
713 | }
714 | }
715 |
716 | # This block sets tags provided as a map in the tags_asg variable (not propagated to ASG instances).
717 | dynamic "tag" {
718 | for_each = merge(var.tags_asg, local.tags_asg)
719 |
720 | content {
721 | key = tag.key
722 | value = tag.value
723 | propagate_at_launch = false
724 | }
725 | }
726 |
727 | depends_on = [aws_ssm_association.ssm_bootstrap_assoc]
728 |
729 | lifecycle {
730 | create_before_destroy = true
731 | }
732 | }
733 |
734 | resource "aws_autoscaling_notification" "scaling_notifications" {
735 | count = var.enable_scaling_notification ? var.asg_count : 0
736 |
737 | group_names = [element(aws_autoscaling_group.autoscalegrp.*.name, count.index)]
738 | topic_arn = var.scaling_notification_topic
739 |
740 | notifications = [
741 | "autoscaling:EC2_INSTANCE_LAUNCH",
742 | "autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
743 | "autoscaling:EC2_INSTANCE_TERMINATE",
744 | "autoscaling:EC2_INSTANCE_TERMINATE_ERROR",
745 | ]
746 | }
747 |
748 | resource "aws_autoscaling_notification" "rs_support_emergency" {
749 | count = var.rackspace_managed ? var.asg_count : 0
750 |
751 | group_names = [element(aws_autoscaling_group.autoscalegrp.*.name, count.index)]
752 | topic_arn = "arn:aws:sns:${data.aws_region.current_region.name}:${data.aws_caller_identity.current_account.account_id}:rackspace-support-emergency"
753 |
754 | notifications = [
755 | "autoscaling:EC2_INSTANCE_LAUNCH_ERROR",
756 | "autoscaling:EC2_INSTANCE_TERMINATE_ERROR",
757 | ]
758 | }
759 |
760 | #
761 | # Provisioning of CloudWatch related resources
762 | #
763 |
764 | locals {
765 | asg_names = [for n in range(var.asg_count) : element(aws_autoscaling_group.autoscalegrp.*.name, n)]
766 |
767 | alarm_dimensions = tolist([for n in range(var.asg_count) : tomap({ "AutoScalingGroupName" = tostring(local.asg_names[n]) })])
768 | }
769 |
770 | module "group_terminating_instances" {
771 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-cloudwatch_alarm//?ref=v0.12.6"
772 |
773 | alarm_count = var.asg_count
774 | alarm_description = "Over ${var.terminated_instances} instances terminated in last 6 hours, generating ticket to investigate."
775 | alarm_name = "${var.name}-GroupTerminatingInstances"
776 | comparison_operator = "GreaterThanThreshold"
777 | customer_alarms_cleared = var.customer_alarms_cleared
778 | customer_alarms_enabled = var.customer_alarms_enabled
779 | dimensions = local.alarm_dimensions[*]
780 | evaluation_periods = 1
781 | metric_name = "GroupTerminatingInstances"
782 | namespace = "AWS/AutoScaling"
783 | notification_topic = var.notification_topic
784 | period = 21600
785 | rackspace_alarms_enabled = var.rackspace_alarms_enabled
786 | rackspace_managed = var.rackspace_managed
787 | severity = "emergency"
788 | statistic = "Sum"
789 | threshold = var.terminated_instances
790 | unit = "Count"
791 | }
792 |
793 | resource "aws_cloudwatch_metric_alarm" "scale_alarm_high" {
794 | count = var.policy_type == "SimpleScaling" && var.enable_scaling_actions == true ? var.asg_count : 0
795 |
796 | alarm_actions = [element(aws_autoscaling_policy.ec2_scale_up_policy.*.arn, count.index)]
797 | alarm_description = "Scale-up if ${var.cw_scaling_metric} ${var.cw_high_operator} ${var.cw_high_threshold}% for ${var.cw_high_period} seconds ${var.cw_high_evaluations} times."
798 | alarm_name = join("-", compact(["ScaleAlarmHigh", var.name, format("%03d", count.index + 1)]))
799 | comparison_operator = var.cw_high_operator
800 | evaluation_periods = var.cw_high_evaluations
801 | metric_name = var.cw_scaling_metric
802 | namespace = "AWS/EC2"
803 | period = var.cw_high_period
804 | statistic = "Average"
805 | threshold = var.cw_high_threshold
806 |
807 | dimensions = {
808 | AutoScalingGroupName = element(aws_autoscaling_group.autoscalegrp.*.name, count.index)
809 | }
810 | }
811 |
812 | resource "aws_cloudwatch_metric_alarm" "scale_alarm_low" {
813 | count = var.policy_type == "SimpleScaling" && var.enable_scaling_actions == true ? var.asg_count : 0
814 |
815 | alarm_actions = [element(aws_autoscaling_policy.ec2_scale_down_policy.*.arn, count.index)]
816 | alarm_description = "Scale-down if ${var.cw_scaling_metric} ${var.cw_low_operator} ${var.cw_low_threshold}% for ${var.cw_low_period} seconds ${var.cw_low_evaluations} times."
817 | alarm_name = join("-", compact(["ScaleAlarmLow", var.name, format("%03d", count.index + 1)]))
818 | comparison_operator = var.cw_low_operator
819 | evaluation_periods = var.cw_low_evaluations
820 | metric_name = var.cw_scaling_metric
821 | namespace = "AWS/EC2"
822 | period = var.cw_low_period
823 | statistic = "Average"
824 | threshold = var.cw_low_threshold
825 |
826 | dimensions = {
827 | AutoScalingGroupName = element(aws_autoscaling_group.autoscalegrp.*.name, count.index)
828 | }
829 | }
830 |
831 | resource "aws_cloudwatch_log_group" "system_logs" {
832 | name = "${var.name}-SystemsLogs"
833 | retention_in_days = var.cloudwatch_log_retention
834 | }
835 |
836 | resource "aws_cloudwatch_log_group" "application_logs" {
837 | name = "${var.name}-ApplicationLogs"
838 | retention_in_days = var.cloudwatch_log_retention
839 | }
840 |
841 | #
842 | # Provisioning of SSM related resources
843 | #
844 |
845 | resource "aws_ssm_document" "ssm_bootstrap_doc" {
846 | content = jsonencode(local.ssm_doc_content)
847 | document_format = "JSON"
848 | document_type = "Command"
849 | name = "SSMDocument-${var.name}"
850 | }
851 |
852 | locals {
853 | cwagentparam_vars = {
854 | application_log = aws_cloudwatch_log_group.application_logs.name
855 | system_log = aws_cloudwatch_log_group.system_logs.name
856 | }
857 |
858 | cwagentparam_object = jsondecode(templatefile("${path.module}/text/${local.cwagent_config}", local.cwagentparam_vars))
859 | }
860 |
861 | resource "aws_ssm_parameter" "cwagentparam" {
862 | count = var.provide_custom_cw_agent_config ? 0 : 1
863 |
864 | description = "${var.name} Cloudwatch Agent configuration"
865 | name = local.cw_config_parameter_name
866 | type = "String"
867 | value = jsonencode(local.cwagentparam_object)
868 | }
869 |
870 | resource "aws_ssm_association" "ssm_bootstrap_assoc" {
871 | name = aws_ssm_document.ssm_bootstrap_doc.name
872 | schedule_expression = var.ssm_association_refresh_rate
873 |
874 | targets {
875 | key = "tag:SSM Target Tag"
876 | values = ["Target-${var.name}"]
877 | }
878 |
879 | depends_on = [aws_ssm_document.ssm_bootstrap_doc]
880 | }
881 |
--------------------------------------------------------------------------------
/outputs.tf:
--------------------------------------------------------------------------------
1 | output "asg_arn_list" {
2 | description = "List of ASG ARNs"
3 | value = aws_autoscaling_group.autoscalegrp.*.arn
4 | }
5 |
6 | output "asg_image_id" {
7 | description = "Image ID used for EC2 provisioning"
8 | value = var.image_id != "" ? var.image_id : data.aws_ami.asg_ami.image_id
9 | }
10 |
11 | output "asg_name_list" {
12 | description = "List of ASG names"
13 | value = aws_autoscaling_group.autoscalegrp.*.name
14 | }
15 |
16 | output "iam_role" {
17 | description = "Name of the created IAM Instance role."
18 | value = element(coalescelist(aws_iam_role.mod_ec2_instance_role.*.id, ["none"]), 0)
19 | }
20 |
--------------------------------------------------------------------------------
/tests/test1/main.tf:
--------------------------------------------------------------------------------
1 | terraform {
2 | required_version = ">= 1.0.0"
3 | }
4 |
5 | provider "aws" {
6 | version = "~> 3.0"
7 | region = "us-west-2"
8 | }
9 |
10 | provider "random" {
11 | version = "~> 3.0"
12 | }
13 |
14 | data "aws_region" "current_region" {}
15 |
16 | locals {
17 | tags = merge({
18 | Environment = "Test"
19 | Purpose = "Testing aws-terraform-ec2_asg"
20 | ServiceProvider = "Rackspace"
21 | Terraform = "true"
22 | }, var.tags)
23 |
24 | tags_asg = {
25 | ASG = "true"
26 | }
27 | }
28 |
29 | resource "random_string" "sqs_rstring" {
30 | length = 18
31 | special = false
32 | upper = false
33 | }
34 |
35 | resource "random_string" "name_rstring" {
36 | length = 8
37 | special = false
38 | }
39 |
40 | module "vpc" {
41 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-vpc_basenetwork?ref=v0.12.7"
42 |
43 | name = "${random_string.name_rstring.result}-ec2-asg-basenetwork-test1"
44 | }
45 |
46 | resource "aws_sqs_queue" "ec2_asg_test_sqs" {
47 | name = "${random_string.sqs_rstring.result}-example-queue"
48 | }
49 |
50 | module "sns" {
51 | source = "git@github.com:rackspace-infrastructure-automation/aws-terraform-sns?ref=v0.12.2"
52 |
53 | create_subscription_1 = true
54 | endpoint_1 = aws_sqs_queue.ec2_asg_test_sqs.arn
55 | name = "${random_string.sqs_rstring.result}-test-topic"
56 | protocol_1 = "sqs"
57 | }
58 |
59 | module "ec2_asg_centos7_encrypted_test" {
60 | source = "../../module"
61 |
62 | asg_count = 1
63 | ec2_os = "centos7"
64 | enable_scaling_notification = true
65 | encrypt_primary_ebs_volume = true
66 | encrypt_secondary_ebs_volume = true
67 | key_pair = "CircleCI"
68 | name = "${random_string.name_rstring.result}-ec2_asg_centos7_encrypted"
69 | scaling_notification_topic = module.sns.topic_arn
70 | secondary_ebs_volume_size = 60
71 | security_groups = [module.vpc.default_sg]
72 | ssm_patching_group = "Group1Patching"
73 | subnets = slice(module.vpc.public_subnets, 0, 2)
74 |
75 | tags = local.tags
76 |
77 | tags_asg = local.tags_asg
78 | }
79 |
80 | module "ec2_asg_centos7_with_codedeploy_test" {
81 | source = "../../module"
82 |
83 | asg_count = 2
84 | ec2_os = "centos7"
85 | enable_scaling_notification = true
86 | install_codedeploy_agent = true
87 | instance_role_managed_policy_arn_count = 3
88 | key_pair = "CircleCI"
89 | name = "${random_string.name_rstring.result}-ec2_asg_centos7_with_codedeploy"
90 | scaling_notification_topic = module.sns.topic_arn
91 | secondary_ebs_volume_size = 60
92 | security_groups = [module.vpc.default_sg]
93 | ssm_patching_group = "Group1Patching"
94 | subnets = slice(module.vpc.public_subnets, 0, 2)
95 |
96 | instance_role_managed_policy_arns = [
97 | "arn:aws:iam::aws:policy/AmazonEC2FullAccess",
98 | "arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole",
99 | "arn:aws:iam::aws:policy/CloudWatchActionsEC2Access",
100 | ]
101 |
102 | ssm_bootstrap_list = [
103 | {
104 | action = "aws:runDocument",
105 | inputs = {
106 | documentPath = "arn:aws:ssm:${data.aws_region.current_region.name}:507897595701:document/Rack-Install_Package",
107 | documentParameters = {
108 | Packages = "bind bindutils"
109 | },
110 | documentType = "SSMDocument"
111 | },
112 | name = "InstallBindAndTools",
113 | timeoutSeconds = 300
114 | },
115 | {
116 | action = "aws:runDocument",
117 | inputs = {
118 | documentPath = "AWS-RunShellScript",
119 | documentParameters = {
120 | commands = ["touch /tmp/myfile"]
121 | },
122 | documentType = "SSMDocument"
123 | },
124 | name = "CreateFile",
125 | timeoutSeconds = 300
126 | },
127 | ]
128 |
129 | tags = local.tags
130 |
131 | tags_asg = local.tags_asg
132 | }
133 |
134 | module "ec2_asg_centos7_no_codedeploy_test" {
135 | source = "../../module"
136 |
137 | ec2_os = "centos7"
138 | enable_scaling_notification = true
139 | install_codedeploy_agent = false
140 | key_pair = "CircleCI"
141 | name = "${random_string.name_rstring.result}-ec2_asg_centos7_no_codedeploy"
142 | scaling_notification_topic = module.sns.topic_arn
143 | secondary_ebs_volume_size = "60"
144 | security_groups = [module.vpc.default_sg]
145 | ssm_patching_group = "Group1Patching"
146 | subnets = slice(module.vpc.public_subnets, 0, 2)
147 |
148 | tags = local.tags
149 |
150 | tags_asg = local.tags_asg
151 | }
152 |
153 | module "ec2_asg_windows_with_codedeploy_test" {
154 | source = "../../module"
155 |
156 | ec2_os = "windows2016"
157 | enable_scaling_actions = false
158 | enable_scaling_notification = true
159 | install_codedeploy_agent = true
160 | instance_role_managed_policy_arn_count = 3
161 | key_pair = "CircleCI"
162 | name = "${random_string.name_rstring.result}-ec2_asg_windows_with_codedeploy"
163 | scaling_notification_topic = module.sns.topic_arn
164 | secondary_ebs_volume_size = 60
165 | security_groups = [module.vpc.default_sg]
166 | ssm_patching_group = "Group1Patching"
167 | subnets = slice(module.vpc.public_subnets, 0, 2)
168 |
169 | instance_role_managed_policy_arns = [
170 | "arn:aws:iam::aws:policy/AmazonEC2FullAccess",
171 | "arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole",
172 | "arn:aws:iam::aws:policy/CloudWatchActionsEC2Access",
173 | ]
174 |
175 | ssm_bootstrap_list = [
176 | {
177 | action = "aws:runDocument",
178 | inputs = {
179 | documentPath = "arn:aws:ssm:${data.aws_region.current_region.name}:507897595701:document/Rack-Install_Datadog",
180 | documentType = "SSMDocument"
181 | },
182 | name = "InstallDataDog",
183 | timeoutSeconds = 300
184 | },
185 | {
186 | action = "aws:runDocument",
187 | inputs = {
188 | documentPath = "AWS-RunPowerShellScript",
189 | documentParameters = {
190 | commands = ["echo $null >> C:\testfile"]
191 | },
192 | documentType = "SSMDocument"
193 | },
194 | name = "CreateFile",
195 | timeoutSeconds = 300
196 | },
197 | ]
198 |
199 | tags = local.tags
200 |
201 | tags_asg = local.tags_asg
202 | }
203 |
204 | module "ec2_asg_windows_no_codedeploy_test" {
205 | source = "../../module"
206 |
207 | ec2_os = "windows2016"
208 | enable_scaling_actions = false
209 | enable_scaling_notification = true
210 | install_codedeploy_agent = false
211 | key_pair = "CircleCI"
212 | name = "${random_string.name_rstring.result}-ec2_asg_windows_no_codedeploy"
213 | scaling_notification_topic = module.sns.topic_arn
214 | secondary_ebs_volume_size = 60
215 | security_groups = [module.vpc.default_sg]
216 | ssm_patching_group = "Group1Patching"
217 | subnets = slice(module.vpc.public_subnets, 0, 2)
218 |
219 | tags = local.tags
220 |
221 | tags_asg = local.tags_asg
222 | }
223 |
224 | module "ec2_asg_amazon2023_no_codedeploy_test" {
225 | source = "../../module"
226 |
227 | ec2_os = "amazon2023"
228 | enable_scaling_notification = true
229 | install_codedeploy_agent = false
230 | key_pair = "CircleCI"
231 | name = "${random_string.name_rstring.result}-ec2_asg_amazon2023_no_codedeploy"
232 | scaling_notification_topic = module.sns.topic_arn
233 | secondary_ebs_volume_size = "60"
234 | security_groups = [module.vpc.default_sg]
235 | ssm_patching_group = "Group1Patching"
236 | subnets = slice(module.vpc.public_subnets, 0, 2)
237 |
238 | tags = local.tags
239 |
240 | tags_asg = local.tags_asg
241 | }
242 |
--------------------------------------------------------------------------------
/tests/test1/variables.tf:
--------------------------------------------------------------------------------
1 | variable "tags" {
2 | description = "Custom tags to apply to all resources."
3 | type = map(string)
4 | default = {}
5 | }
6 |
--------------------------------------------------------------------------------
/text/amazon_linux_userdata.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ${initial_commands}
4 |
5 | # Ensure SSM installed on Amazon Linux
6 | # in cases where it is not available / removed
7 | ssm_running=$( ps -ef | grep ['a']mazon-ssm-agent | wc -l )
8 | if [[ $ssm_running != "0" ]]; then
9 | echo -e "amazon-ssm-agent already running"
10 | else
11 | if [[ -r "/tmp/ssm_agent_install" ]]; then : ;
12 | else mkdir -p /tmp/ssm_agent_install; fi
13 | curl https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm -o /tmp/ssm_agent_install/amazon-ssm-agent.rpm
14 | rpm -Uvh /tmp/ssm_agent_install/amazon-ssm-agent.rpm
15 | ssm_running=$( ps -ef | grep ['a']mazon-ssm-agent | wc -l )
16 | # Amazon Linux 2
17 | systemctl=$( command -v systemctl | wc -l )
18 | if [[ $systemctl != "0" ]]; then
19 | systemctl enable amazon-ssm-agent
20 | if [[ $ssm_running == "0" ]]; then
21 | systemctl start amazon-ssm-agent
22 | fi
23 | fi
24 | fi
25 |
26 | ${final_commands}
27 |
--------------------------------------------------------------------------------
/text/debian_userdata.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -xe
2 |
3 | function lock_wait {
4 | endtime=$(( $(date +%s) + 300 ))
5 | set +e
6 | while [ $(date +%s) -lt $endtime ]; do
7 | "$@" && break
8 | sleep 15
9 | done
10 | set -e
11 | }
12 |
13 | function install_ssm_deb {
14 | if [[ -r "/tmp/ssm_agent_install" ]]; then : ;
15 | else
16 | mkdir -p /tmp/ssm_agent_install
17 | fi
18 | curl https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb -o /tmp/ssm_agent_install/amazon-ssm-agent.deb
19 | lock_wait dpkg -i /tmp/ssm_agent_install/amazon-ssm-agent.deb
20 |
21 | if ps -ef | grep -q [a]mazon-ssm-agent ;then
22 | ssm_running="yes"
23 | else
24 | ssm_running="no"
25 | fi
26 |
27 | if command -v systemctl ; then
28 | systemctl enable amazon-ssm-agent
29 | if [[ $ssm_running == "no" ]]; then
30 | systemctl start amazon-ssm-agent
31 | fi
32 | else
33 | if [[ $ssm_running == "no" ]]; then
34 | start amazon-ssm-agent
35 | fi
36 | fi
37 |
38 | return 0
39 | }
40 |
41 | function install_aws_cli_v2 {
42 | mkdir -p /opt/aws/aws
43 | curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /opt/aws/awscliv2.zip && \
44 | unzip -o /opt/aws/awscliv2.zip -d /opt/aws && \
45 | /opt/aws/aws/install -u
46 | }
47 |
48 | export LC_ALL=C.UTF-8
49 | export DEBIAN_FRONTEND=noninteractive
50 |
51 | ${initial_commands}
52 |
53 | exec 1> >(logger -s -t $(basename $0)) 2>&1
54 |
55 | lock_wait apt-get update
56 | lock_wait apt-get -y install python-setuptools python3-pip unzip
57 |
58 | # Install AWSCLIv2
59 | install_aws_cli_v2
60 |
61 | if ps -ef | grep -q [a]mazon-ssm-agent ;then
62 | ssm_running="yes"
63 | else
64 | ssm_running="no"
65 | fi
66 |
67 | if [[ $ssm_running == "yes" ]]; then
68 | echo "amazon-ssm-agent already running"
69 | else
70 | # use deb installer
71 | install_ssm_deb
72 | fi
--------------------------------------------------------------------------------
/text/linux_cw_agent_param.json:
--------------------------------------------------------------------------------
1 | {
2 | "metrics": {
3 | "append_dimensions": {
4 | "InstanceId": "$${aws:InstanceId}"
5 | },
6 | "aggregation_dimensions": [
7 | ["InstanceId"],
8 | ["InstanceId", "device"]
9 | ],
10 | "metrics_collected": {
11 | "mem": {
12 | "metrics_collection_interval": 60,
13 | "measurement": ["used_percent"]
14 | },
15 | "disk": {
16 | "ignore_file_system_types": [
17 | "devtmpfs",
18 | "tmpfs",
19 | "devfs",
20 | "rootfs",
21 | "squashfs"
22 | ],
23 | "metrics_collection_interval": 60,
24 | "resources": ["*"],
25 | "measurement": [
26 | "used_percent",
27 | "disk_total",
28 | "disk_used"
29 | ]
30 | }
31 | }
32 | },
33 | "logs": {
34 | "force_flush_interval": 60,
35 | "logs_collected": {
36 | "files": {
37 | "collect_list": [
38 | {
39 | "file_path": "/var/log/cloud-init-output.log",
40 | "log_group_name": "${system_log}",
41 | "log_stream_name": "{instance_id}/cloud-init-output.log"
42 | },
43 | {
44 | "timestamp_format": "%b %d %H:%M:%S",
45 | "file_path": "/var/log/cloud-init.log",
46 | "log_group_name": "${system_log}",
47 | "log_stream_name": "{instance_id}/cloud-init.log"
48 | },
49 | {
50 | "timestamp_format": "%Y-%m-%d %H:%M:%S",
51 | "multi_line_start_pattern": "{timestamp_format}",
52 | "file_path": "/var/log/amazon/ssm/amazon-ssm-agent.log",
53 | "log_group_name": "${system_log}",
54 | "log_stream_name": "{instance_id}/amazon-ssm-agent.log"
55 | },
56 | {
57 | "timestamp_format": "%Y-%m-%d %H:%M:%S",
58 | "multi_line_start_pattern": "{timestamp_format}",
59 | "file_path": "/var/log/amazon/ssm/errors.log",
60 | "log_group_name": "${system_log}",
61 | "log_stream_name": "{instance_id}/amazon-ssm-errors.log"
62 | },
63 | {
64 | "timestamp_format": "%d/%b/%Y:%H:%M:%S",
65 | "file_path": "/var/log/httpd/access*",
66 | "log_group_name": "${application_log}",
67 | "log_stream_name": "{instance_id}/httpd-access"
68 | },
69 | {
70 | "timestamp_format": "%d/%b/%Y:%H:%M:%S",
71 | "file_path": "/var/log/httpd/error*",
72 | "log_group_name": "${application_log}",
73 | "log_stream_name": "{instance_id}/httpd-error"
74 | },
75 | {
76 | "timestamp_format": "%d/%b/%Y:%H:%M:%S",
77 | "file_path": "/var/log/apache2/access*",
78 | "log_group_name": "${application_log}",
79 | "log_stream_name": "{instance_id}/apache2-access"
80 | },
81 | {
82 | "timestamp_format": "%d/%b/%Y:%H:%M:%S",
83 | "file_path": "/var/log/apache2/error*",
84 | "log_group_name": "${application_log}",
85 | "log_stream_name": "{instance_id}/apache2-error"
86 | },
87 | {
88 | "timestamp_format": "%d/%b/%Y:%H:%M:%S",
89 | "file_path": "/var/log/nginx/access*",
90 | "log_group_name": "${application_log}",
91 | "log_stream_name": "{instance_id}/nginx-access"
92 | },
93 | {
94 | "timestamp_format": "%d/%b/%Y:%H:%M:%S",
95 | "file_path": "/var/log/nginx/error*",
96 | "log_group_name": "${application_log}",
97 | "log_stream_name": "{instance_id}/nginx-error"
98 | }
99 | ]
100 | }
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/text/rhel_centos_7_userdata.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -xe
2 |
3 | ${initial_commands}
4 |
5 | exec 1> >(logger -s -t $(basename $0)) 2>&1
6 |
7 | curl https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm -o /tmp/epel-release-latest-7.noarch.rpm
8 | rpm -qa | grep -q epel-release || yum install -y /tmp/epel-release-latest-7.noarch.rpm
9 |
10 | #install awscliv2
11 | yum install -y unzip
12 | mkdir -p /tmp/awscliv2
13 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2/awscliv2.zip"
14 | unzip /tmp/awscliv2/awscliv2.zip -d /tmp/awscliv2/
15 | ./tmp/awscliv2/aws/install
16 |
17 | ssm_running=$( ps -ef | grep [a]mazon-ssm-agent | wc -l )
18 | if [[ $ssm_running != "0" ]]; then
19 | echo -e "amazon-ssm-agent already running"
20 | else
21 | if [[ -r "/tmp/ssm_agent_install" ]]; then : ;
22 | else mkdir -p /tmp/ssm_agent_install; fi
23 | curl https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm -o /tmp/ssm_agent_install/amazon-ssm-agent.rpm
24 | rpm -Uvh /tmp/ssm_agent_install/amazon-ssm-agent.rpm
25 | ssm_running=$( ps -ef | grep [a]mazon-ssm-agent | wc -l )
26 | systemctl=$( command -v systemctl | wc -l )
27 | if [[ $systemctl != "0" ]]; then
28 | systemctl enable amazon-ssm-agent
29 | if [[ $ssm_running == "0" ]]; then
30 | systemctl start amazon-ssm-agent
31 | fi
32 | else
33 | if [[ $ssm_running == "0" ]]; then
34 | start amazon-ssm-agent
35 | fi
36 | fi
37 | fi
38 |
39 | ${final_commands}
40 |
--------------------------------------------------------------------------------
/text/rhel_centos_8_userdata.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -xe
2 |
3 | ${initial_commands}
4 |
5 | exec 1> >(logger -s -t $(basename $0)) 2>&1
6 |
7 | curl https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm -o /tmp/epel-release-latest-8.noarch.rpm
8 | rpm -qa | grep -q epel-release || yum install -y /tmp/epel-release-latest-8.noarch.rpm
9 |
10 | #install awscliv2
11 | dnf makecache
12 | dnf -y install unzip
13 | mkdir -p /tmp/awscliv2
14 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2/awscliv2.zip"
15 | unzip /tmp/awscliv2/awscliv2.zip -d /tmp/awscliv2/
16 | ./tmp/awscliv2/aws/install
17 |
18 | ssm_running=$( ps -ef | grep [a]mazon-ssm-agent | wc -l )
19 | if [[ $ssm_running != "0" ]]; then
20 | echo -e "amazon-ssm-agent already running"
21 | exit 0
22 | else
23 | dnf install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
24 | ssm_running=$( ps -ef | grep [a]mazon-ssm-agent | wc -l )
25 | systemctl=$( command -v systemctl | wc -l )
26 | if [[ $systemctl != "0" ]]; then
27 | systemctl enable amazon-ssm-agent
28 | if [[ $ssm_running == "0" ]]; then
29 | systemctl start amazon-ssm-agent
30 | fi
31 | else
32 | if [[ $ssm_running == "0" ]]; then
33 | start amazon-ssm-agent
34 | fi
35 | fi
36 | fi
37 |
38 | ${final_commands}
39 |
--------------------------------------------------------------------------------
/text/ubuntu_userdata.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -xe
2 |
3 | function lock_wait {
4 | endtime=$(( $(date +%s) + 300 ))
5 | set +e
6 | while [ $(date +%s) -lt $endtime ]; do
7 | "$@" && break
8 | sleep 15
9 | done
10 | set -e
11 | }
12 |
13 | function install_ssm_deb {
14 | if [[ -r "/tmp/ssm_agent_install" ]]; then : ;
15 | else
16 | mkdir -p /tmp/ssm_agent_install
17 | fi
18 | curl https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/debian_amd64/amazon-ssm-agent.deb -o /tmp/ssm_agent_install/amazon-ssm-agent.deb
19 | lock_wait dpkg -i /tmp/ssm_agent_install/amazon-ssm-agent.deb
20 |
21 | if ps -ef | grep -q [a]mazon-ssm-agent ;then
22 | ssm_running="yes"
23 | else
24 | ssm_running="no"
25 | fi
26 |
27 | if command -v systemctl ; then
28 | systemctl enable amazon-ssm-agent
29 | if [[ $ssm_running == "no" ]]; then
30 | systemctl start amazon-ssm-agent
31 | fi
32 | else
33 | if [[ $ssm_running == "no" ]]; then
34 | start amazon-ssm-agent
35 | fi
36 | fi
37 |
38 | return 0
39 | }
40 |
41 | function install_ssm_snap {
42 | if snap install amazon-ssm-agent --classic; then
43 | echo "snap should be installed"
44 | snap list amazon-ssm-agent
45 | else
46 | # handle case where it actually installed but timed out
47 | systemctl start snap.amazon-ssm-agent.amazon-ssm-agent.service
48 | systemctl stop snap.amazon-ssm-agent.amazon-ssm-agent.service
49 | snap start amazon-ssm-agent --enable
50 | fi
51 | return 0
52 | }
53 |
54 | export LC_ALL=C.UTF-8
55 | export DEBIAN_FRONTEND=noninteractive
56 | lock_wait apt-get update
57 |
58 | ${initial_commands}
59 |
60 | exec 1> >(logger -s -t $(basename $0)) 2>&1
61 |
62 | #install awscliv2
63 | lock_wait apt-get install unzip
64 | mkdir -p /tmp/awscliv2
65 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2/awscliv2.zip"
66 | unzip /tmp/awscliv2/awscliv2.zip -d /tmp/awscliv2/
67 | ./tmp/awscliv2/aws/install
68 |
69 |
70 |
71 | if ps -ef | grep -q [a]mazon-ssm-agent ;then
72 | ssm_running="yes"
73 | else
74 | ssm_running="no"
75 | fi
76 |
77 | if [[ $ssm_running == "yes" ]]; then
78 | echo "amazon-ssm-agent already running"
79 | else
80 | source /etc/os-release
81 | #always uses snap for 18.04 and higher
82 | if snap list amazon-ssm-agent | grep -q amazon-ssm-agent ; then
83 | echo "snap is installed ... starting"
84 | snap start amazon-ssm-agent
85 | else
86 | install_ssm_snap
87 | fi
88 | fi
89 |
90 | ${final_commands}
91 |
--------------------------------------------------------------------------------
/text/windows_cw_agent_param.json:
--------------------------------------------------------------------------------
1 | {
2 | "logs": {
3 | "force_flush_interval": 60,
4 | "logs_collected": {
5 | "files": {
6 | "collect_list": [
7 | {
8 | "file_path": "C:\\Program Files\\Amazon\\Ec2ConfigService\\Logs\\Ec2Configlog.txt",
9 | "log_group_name": "${system_log}",
10 | "log_stream_name": "{instance_id}/Ec2Config.log",
11 | "timestamp_format": "%Y-%m-%dT%H:%M:%S",
12 | "multi_line_start_pattern": "{timestamp_format}"
13 | },
14 | {
15 | "file_path": "c:\\ProgramData\\Amazon\\SSM\\Logs\\amazon-ssm-agent.log",
16 | "log_group_name": "${system_log}",
17 | "log_stream_name": "{instance_id}/amazon-ssm-agent.log",
18 | "timestamp_format": "%Y-%m-%d %H:%M:%S",
19 | "multi_line_start_pattern": "{timestamp_format}"
20 | },
21 | {
22 | "file_path": "c:\\ProgramData\\Amazon\\SSM\\Logs\\errors.log",
23 | "log_group_name": "${system_log}",
24 | "log_stream_name": "{instance_id}/amazon-ssm-errors.log",
25 | "timestamp_format": "%Y-%m-%d %H:%M:%S",
26 | "multi_line_start_pattern": "{timestamp_format}"
27 | },
28 | {
29 | "file_path": "C:\\inetpub\\logs\\LogFiles\\W3SVC1\\*.log",
30 | "log_group_name": "${application_log}",
31 | "log_stream_name": "{instance_id}/IISLogs",
32 | "timestamp_format": "%Y-%m-%d %H:%M:%S"
33 | }
34 | ]
35 | },
36 | "windows_events": {
37 | "collect_list": [
38 | {
39 | "event_name": "System",
40 | "event_levels": ["INFORMATION", "WARNING", "ERROR", "CRITICAL"],
41 | "log_group_name": "${system_log}",
42 | "log_stream_name": "{instance_id}/System"
43 | },
44 | {
45 | "event_name": "Application",
46 | "event_levels": ["INFORMATION", "WARNING", "ERROR", "CRITICAL"],
47 | "log_group_name": "${system_log}",
48 | "log_stream_name": "{instance_id}/Application"
49 | },
50 | {
51 | "event_name": "Security",
52 | "event_levels": ["INFORMATION", "WARNING", "ERROR", "CRITICAL"],
53 | "log_group_name": "${system_log}",
54 | "log_stream_name": "{instance_id}/Security"
55 | }
56 | ]
57 | }
58 | }
59 | },
60 | "metrics": {
61 | "append_dimensions": {
62 | "InstanceId": "$${aws:InstanceId}"
63 | },
64 | "aggregation_dimensions": [["InstanceId"]],
65 | "metrics_collected": {
66 | "LogicalDisk": {
67 | "measurement": [{ "name": "% Free Space"}],
68 | "metrics_collection_interval": 60,
69 | "resources": ["*"]
70 | },
71 | "Memory": {
72 | "measurement": ["Available MBytes", {"name": "% Committed Bytes In Use"}],
73 | "metrics_collection_interval": 60
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/text/windows_userdata.ps1:
--------------------------------------------------------------------------------
1 |
2 | ${initial_commands}
3 |
4 | ${final_commands}
5 |
6 |
--------------------------------------------------------------------------------
/variables.tf:
--------------------------------------------------------------------------------
1 | variable "additional_ssm_bootstrap_list" {
2 | description = "A list of maps consisting of main step actions, to be appended to SSM associations. Please see usage.tf.example in this repo for examples.
(DEPRECATED) This variable will be removed in future releases in favor of the `ssm_bootstrap_list` variable."
3 | type = list(map(string))
4 | default = []
5 | }
6 |
7 | variable "additional_tags" {
8 | description = "Additional tags to be added to the ASG instance(s). Format: list of maps. Please see usage.tf.example in this repo for examples.
(DEPRECATED) This variable will be removed in future releases in favor of the `tags` and `tags_asg` variables."
9 | type = list(map(string))
10 | default = []
11 | }
12 |
13 | variable "alb_resource_label" {
14 | description = "Enter the ALB and Target group in this format : app/load-balancer-name/load-balancer-id/targetgroup/target-group-name/target-group-id"
15 | type = string
16 | default = null
17 | }
18 |
19 | variable "asg_count" {
20 | description = "Number of identical ASG's to deploy"
21 | type = string
22 | default = "1"
23 | }
24 |
25 | variable "asg_wait_for_capacity_timeout" {
26 | description = "A maximum duration that Terraform should wait for ASG instances to be healthy before timing out."
27 | type = string
28 | default = "10m"
29 | }
30 |
31 | variable "backup_tag_value" {
32 | description = "Value of the 'Backup' tag, used to assign to the AWS Backup configuration"
33 | type = string
34 | default = "False"
35 | }
36 |
37 | variable "cloudwatch_log_retention" {
38 | description = "The number of days to retain Cloudwatch Logs for this instance."
39 | type = string
40 | default = "30"
41 | }
42 |
43 | variable "customer_alarms_cleared" {
44 | description = "Specifies whether alarms will notify customers when returning to an OK status."
45 | type = bool
46 | default = false
47 | }
48 |
49 | variable "customer_alarms_enabled" {
50 | description = "Specifies whether alarms will notify customers. Automatically enabled if rackspace_managed is set to false"
51 | type = bool
52 | default = false
53 | }
54 |
55 | variable "custom_cw_agent_config_ssm_param" {
56 | description = "SSM Parameter Store name that contains a custom CloudWatch agent configuration that you would like to use as an alternative to the default provided."
57 | type = string
58 | default = ""
59 | }
60 |
61 | variable "cw_high_evaluations" {
62 | description = "The number of periods over which data is compared to the specified threshold."
63 | type = string
64 | default = "3"
65 | }
66 |
67 | variable "cw_high_operator" {
68 | description = "Math operator used by CloudWatch for alarms and triggers."
69 | type = string
70 | default = "GreaterThanThreshold"
71 | }
72 |
73 | variable "cw_high_period" {
74 | description = "Time the specified statistic is applied. Must be in seconds that is also a multiple of 60."
75 | type = string
76 | default = "60"
77 | }
78 |
79 | variable "cw_high_threshold" {
80 | description = "The value against which the specified statistic is compared."
81 | type = string
82 | default = "60"
83 | }
84 |
85 | variable "cw_low_evaluations" {
86 | description = "The number of periods over which data is compared to the specified threshold."
87 | type = string
88 | default = "3"
89 | }
90 |
91 | variable "cw_low_operator" {
92 | description = "Math operator used by CloudWatch for alarms and triggers."
93 | type = string
94 | default = "LessThanThreshold"
95 | }
96 |
97 | variable "cw_low_period" {
98 | description = "Time the specified statistic is applied. Must be in seconds that is also a multiple of 60."
99 | type = string
100 | default = "300"
101 | }
102 |
103 | variable "cw_low_threshold" {
104 | description = "The value against which the specified statistic is compared."
105 | type = string
106 | default = "30"
107 | }
108 |
109 | variable "cw_scaling_metric" {
110 | description = "The metric to be used for scaling."
111 | type = string
112 | default = "CPUUtilization"
113 | }
114 |
115 | variable "detailed_monitoring" {
116 | description = "Enable Detailed Monitoring? true or false"
117 | type = bool
118 | default = true
119 | }
120 |
121 | variable "disable_scale_in" {
122 | description = "Disable scale in to create only a scale-out policy in Target Tracking Policy."
123 | type = bool
124 | default = false
125 | }
126 |
127 | variable "ec2_os" {
128 | description = "Intended Operating System/Distribution of Instance. Valid inputs are: `amazon2`, `amazoneks`, `amazonecs`, `rhel7`, `rhel8`, `centos7`, `ubuntu18`, `ubuntu20`, `windows2012r2`, `windows2016`, `windows2019`"
129 | type = string
130 | }
131 |
132 | variable "ec2_scale_down_adjustment" {
133 | description = "Number of EC2 instances to scale down by at a time. Positive numbers will be converted to negative."
134 | type = string
135 | default = "-1"
136 | }
137 |
138 | variable "ec2_scale_down_cool_down" {
139 | description = "Time in seconds before any further trigger-related scaling can occur."
140 | type = string
141 | default = "60"
142 | }
143 |
144 | variable "ec2_scale_up_adjustment" {
145 | description = "Number of EC2 instances to scale up by at a time."
146 | type = string
147 | default = "1"
148 | }
149 |
150 | variable "ec2_scale_up_cool_down" {
151 | description = "Time in seconds before any further trigger-related scaling can occur."
152 | type = string
153 | default = "60"
154 | }
155 |
156 | variable "enable_ebs_optimization" {
157 | description = "Use EBS Optimized? true or false"
158 | type = bool
159 | default = false
160 | }
161 |
162 | variable "enable_rolling_updates" {
163 | description = "Should this autoscaling group be targeted by the ASG Instance Replacement tool to ensure all instances are using thelatest launch configuration."
164 | type = bool
165 | default = true
166 | }
167 |
168 | variable "enable_scaling_actions" {
169 | description = "Should this autoscaling group be configured with scaling alarms to manage the desired count. Set this variable to false if another process will manage the desired count, such as EKS Cluster Autoscaler."
170 | type = bool
171 | default = true
172 | }
173 |
174 | variable "enable_scaling_notification" {
175 | description = "true or false. If 'scaling_notification_topic' is set to a non-empty string, this must be set to true. Otherwise, set to false. This variable exists due to a terraform limitation with using count and computed values as conditionals"
176 | type = bool
177 | default = false
178 | }
179 |
180 | variable "enabled_asg_metrics" {
181 | description = "List of ASG metrics desired. This can only contain the following values: `GroupDesiredCapacity`, `GroupInServiceCapacity`, `GroupPendingCapacity`, `GroupMinSize`, `GroupMaxSize`, `GroupInServiceInstances`, `GroupPendingInstances`, `GroupStandbyInstances`, `GroupStandbyCapacity`, `GroupTerminatingCapacity`, `GroupTerminatingInstances`, `GroupTotalCapacity`, `GroupTotalInstances`."
182 | type = list(string)
183 | default = []
184 | }
185 |
186 | variable "encrypt_primary_ebs_volume" {
187 | description = "Encrypt root EBS Volume? true or false"
188 | type = bool
189 | default = false
190 | }
191 |
192 | variable "encrypt_secondary_ebs_volume" {
193 | description = "Encrypt secondary EBS Volume? true or false"
194 | type = bool
195 | default = false
196 | }
197 |
198 | variable "environment" {
199 | description = "Application environment for which this network is being created. Preferred value are Development, Integration, PreProduction, Production, QA, Staging, or Test"
200 | type = string
201 | default = "Development"
202 | }
203 |
204 | variable "final_userdata_commands" {
205 | description = "Commands to be given at the end of userdata for an instance. This should generally not include bootstrapping or ssm install."
206 | type = string
207 | default = ""
208 | }
209 |
210 | variable "health_check_grace_period" {
211 | description = "Number of seconds grace during which no autoscaling actions will be taken."
212 | type = string
213 | default = "300"
214 | }
215 |
216 | variable "health_check_type" {
217 | description = "Define the type of healthcheck for the AutoScaling group."
218 | type = string
219 | default = "EC2"
220 | }
221 |
222 | variable "image_id" {
223 | description = "The AMI ID to be used to build the EC2 Instance. If not provided, an AMI ID will be queried with an OS specified in variable ec2_os."
224 | type = string
225 | default = ""
226 | }
227 |
228 | variable "initial_userdata_commands" {
229 | description = "Commands to be given at the start of userdata for an instance. This should generally not include bootstrapping or ssm install."
230 | type = string
231 | default = ""
232 | }
233 |
234 | variable "install_codedeploy_agent" {
235 | description = "Install codedeploy agent on instance(s)? true or false"
236 | type = bool
237 | default = false
238 | }
239 |
240 | variable "instance_profile_override" {
241 | description = "Optionally provide an instance profile. Any override profile should contain the permissions required for Rackspace support tooling to continue to function if required."
242 | type = bool
243 | default = false
244 | }
245 |
246 | variable "instance_profile_override_name" {
247 | description = "Provide an instance profile name. Any override profile should contain the permissions required for Rackspace support tooling to continue to function if required. To use this set `instance_profile_override` to `true`."
248 | type = string
249 | default = ""
250 | }
251 |
252 | variable "instance_role_managed_policy_arn_count" {
253 | description = "The number of policy ARNs provided/set in variable 'instance_role_managed_policy_arns'"
254 | type = string
255 | default = "0"
256 | }
257 |
258 | variable "instance_role_managed_policy_arns" {
259 | description = "List of IAM policy ARNs for the InstanceRole IAM role. IAM ARNs can be found within the Policies section of the AWS IAM console. e.g. ['arn:aws:iam::aws:policy/AmazonEC2FullAccess', 'arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore', 'arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetRole']"
260 | type = list(string)
261 | default = []
262 | }
263 |
264 | variable "instance_type" {
265 | description = "EC2 Instance Type e.g. 't2.micro'"
266 | type = string
267 | default = "t2.micro"
268 | }
269 |
270 | variable "instance_warm_up_time" {
271 | description = "Specify the Instance Warm Up time for Target Tracking Policy."
272 | type = string
273 | default = "300"
274 | }
275 |
276 | variable "key_pair" {
277 | description = "Name of an existing EC2 KeyPair to enable SSH access to the instances."
278 | type = string
279 | default = ""
280 | }
281 |
282 | variable "load_balancer_names" {
283 | description = "A list of Classic load balancers associated with this Auto Scaling group."
284 | type = list(string)
285 | default = []
286 | }
287 |
288 | variable "name" {
289 | description = "Name to be used for the provisioned EC2 instance(s), ASG(s), and other resources provisioned in this module"
290 | type = string
291 | }
292 |
293 | variable "notification_topic" {
294 | description = "List of SNS Topic ARNs to use for customer notifications."
295 | type = list(string)
296 | default = []
297 | }
298 |
299 | variable "perform_ssm_inventory_tag" {
300 | description = "Determines whether Instance is tracked via System Manager Inventory."
301 | type = string
302 | default = "True"
303 | }
304 |
305 | variable "policy_type" {
306 | description = "Enter scaling policy type. Allowed values are : SimpleScaling or TargetTrackingScaling"
307 | type = string
308 | default = "SimpleScaling"
309 | }
310 |
311 | variable "primary_ebs_volume_iops" {
312 | description = "Iops value required for use with io1 EBS volumes. This value should be 3 times the EBS volume size"
313 | type = string
314 | default = "0"
315 | }
316 |
317 | variable "primary_ebs_volume_size" {
318 | description = "EBS Volume Size in GB"
319 | type = string
320 | default = "60"
321 | }
322 |
323 | variable "primary_ebs_volume_type" {
324 | description = "EBS Volume Type. e.g. gp2, io1, st1, sc1"
325 | type = string
326 | default = "gp2"
327 | }
328 |
329 | variable "provide_custom_cw_agent_config" {
330 | description = "Set to true if a custom cloudwatch agent configuration has been provided in variable custom_cw_agent_config_ssm_param."
331 | type = bool
332 | default = false
333 | }
334 |
335 | variable "rackspace_alarms_enabled" {
336 | description = "Specifies whether alarms will create a Rackspace ticket. Ignored if rackspace_managed is set to false."
337 | type = bool
338 | default = false
339 | }
340 |
341 | variable "rackspace_managed" {
342 | description = "Boolean parameter controlling if instance will be fully managed by Rackspace support teams, created CloudWatch alarms that generate tickets, and utilize Rackspace managed SSM documents."
343 | type = bool
344 | default = true
345 | }
346 |
347 | variable "scaling_max" {
348 | description = "The maximum size of the Auto Scaling group."
349 | type = string
350 | default = "2"
351 | }
352 |
353 | variable "scaling_min" {
354 | description = "The minimum count of EC2 instances in the Auto Scaling group."
355 | type = string
356 | default = "1"
357 | }
358 |
359 | variable "scaling_notification_topic" {
360 | description = "SNS Topic ARN to notify if there are any scaling operations. OPTIONAL"
361 | type = string
362 | default = ""
363 | }
364 |
365 | variable "secondary_ebs_volume_existing_id" {
366 | description = "The Snapshot ID of an existing EBS volume you want to use for the secondary volume. i.e. snap-0ad8580e3ac34a9f1"
367 | type = string
368 | default = ""
369 | }
370 |
371 | variable "secondary_ebs_volume_iops" {
372 | description = "Iops value required for use with io1 EBS volumes. This value should be 3 times the EBS volume size"
373 | type = string
374 | default = "0"
375 | }
376 |
377 | variable "secondary_ebs_volume_size" {
378 | description = "EBS Volume Size in GB"
379 | type = string
380 | default = ""
381 | }
382 |
383 | variable "secondary_ebs_volume_type" {
384 | description = "EBS Volume Type. e.g. gp2, io1, st1, sc1"
385 | type = string
386 | default = "gp2"
387 | }
388 |
389 | variable "security_groups" {
390 | description = "A list of EC2 security IDs to assign to this resource."
391 | type = list(string)
392 | }
393 |
394 | variable "ssm_association_refresh_rate" {
395 | description = "A cron or rate pattern to define the SSM Association refresh schedule, defaulting to once per day. See https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-cron.html for more details. Schedule can be disabled by providing an empty string."
396 | type = string
397 | default = "rate(1 day)"
398 | }
399 |
400 | variable "ssm_bootstrap_list" {
401 | description = "A list of objects consisting of actions, to be appended to SSM associations. Please see usage.tf.example in this repo for examples."
402 | type = any
403 | default = []
404 | }
405 |
406 | variable "ssm_patching_group" {
407 | description = "Group ID to be used by System Manager for Patching"
408 | type = string
409 | default = ""
410 | }
411 |
412 | variable "subnets" {
413 | description = "List of subnets for Application. e.g. ['subnet-8da92df7', 'subnet-9e5dc5f6', 'subnet-497eaf33']"
414 | type = list(string)
415 | }
416 |
417 | variable "tags" {
418 | description = "A map of tags to apply to all resources. These tags will all be propagated to ASG instances and set on all other resources."
419 | type = map(string)
420 | default = {}
421 | }
422 |
423 | variable "tags_asg" {
424 | description = "A map of tags to apply to the ASG itself. These tags will not be propagated to ASG instances or set on any other resources."
425 | type = map(string)
426 | default = {}
427 | }
428 |
429 | variable "target_group_arns" {
430 | description = "A list of Amazon Resource Names (ARN) of target groups to associate with the Auto Scaling group."
431 | type = list(string)
432 | default = []
433 | }
434 |
435 | variable "target_value" {
436 | description = "Enter the target value for Target Scaling Policy metrics."
437 | type = string
438 | default = "50"
439 | }
440 |
441 | variable "tenancy" {
442 | description = "The placement tenancy for EC2 devices. e.g. host, default, dedicated"
443 | type = string
444 | default = "default"
445 | }
446 |
447 | variable "terminated_instances" {
448 | description = "Specifies the maximum number of instances that can be terminated in a six hour period without generating a Cloudwatch Alarm."
449 | type = string
450 | default = "30"
451 | }
452 |
453 | variable "tracking_policy_metric" {
454 | description = "Allowed Values are: ASGAverageCPUUtilization, ASGAverageNetworkIn, ASGAverageNetworkOut, ALBRequestCountPerTarget"
455 | type = string
456 | default = "ASGAverageCPUUtilization"
457 | }
458 | variable "metadata_http_endpoint" {
459 | description = "Whether the metadata service is available. Valid values include enabled or disabled."
460 | type = string
461 | default = "enabled"
462 | }
463 |
464 | variable "metadata_http_put_response_hop_limit" {
465 | description = " Desired HTTP PUT response hop limit for instance metadata requests. The larger the number, the further instance metadata requests can travel. Valid values are integer from 1 to 64"
466 | type = number
467 | default = 1
468 | }
469 |
470 | variable "metadata_http_tokens" {
471 | description = "Whether or not the metadata service requires session tokens, also referred to as Instance Metadata Service Version 2 (IMDSv2). Valid values include optional or required."
472 | type = string
473 | default = "optional"
474 | }
475 |
476 | variable "metadata_instance_metadata_tags" {
477 | description = "Enables or disables access to instance tags from the instance metadata service. Valid values include enabled or disabled"
478 | type = string
479 | default = "disabled"
480 | }
481 |
--------------------------------------------------------------------------------