Skip to content

Commit ab899fc

Browse files
committed
feat: Updates from testing, add upgrade guide
1 parent 50282b0 commit ab899fc

File tree

8 files changed

+301
-182
lines changed

8 files changed

+301
-182
lines changed

README.md

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,6 @@ module "ec2_instance" {
7272
}
7373
```
7474

75-
## Module wrappers
76-
77-
Users of this Terraform module can create multiple similar resources by using [`for_each` meta-argument within `module` block](https://www.terraform.io/language/meta-arguments/for_each) which became available in Terraform 0.13.
78-
79-
Users of Terragrunt can achieve similar results by using modules provided in the [wrappers](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/wrappers) directory, if they prefer to reduce amount of configuration files.
80-
8175
## Examples
8276

8377
- [Complete EC2 instance](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/complete)
@@ -87,7 +81,7 @@ Users of Terragrunt can achieve similar results by using modules provided in the
8781

8882
This module does not support encrypted AMI's out of the box however it is easy enough for you to generate one for use
8983

90-
This example creates an encrypted image from the latest ubuntu 16.04 base image.
84+
This example creates an encrypted image from the latest ubuntu 20.04 base image.
9185

9286
```hcl
9387
provider "aws" {
@@ -135,8 +129,6 @@ data "aws_ami" "encrypted-ami" {
135129

136130
The following combinations are supported to conditionally create resources:
137131

138-
- Disable resource creation (no resources created):
139-
140132
```hcl
141133
module "ec2_instance" {
142134
source = "terraform-aws-modules/ec2-instance/aws"
@@ -188,6 +180,7 @@ No modules.
188180
| Name | Type |
189181
|------|------|
190182
| [aws_ebs_volume.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume) | resource |
183+
| [aws_ec2_tag.spot_instance](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ec2_tag) | resource |
191184
| [aws_eip.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource |
192185
| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
193186
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
@@ -262,16 +255,17 @@ No modules.
262255
| <a name="input_private_ip"></a> [private\_ip](#input\_private\_ip) | Private IP address to associate with the instance in a VPC | `string` | `null` | no |
263256
| <a name="input_putin_khuylo"></a> [putin\_khuylo](#input\_putin\_khuylo) | Do you agree that Putin doesn't respect Ukrainian sovereignty and territorial integrity? More info: https://en.wikipedia.org/wiki/Putin_khuylo! | `bool` | `true` | no |
264257
| <a name="input_region"></a> [region](#input\_region) | Region where the resource(s) will be managed. Defaults to the Region set in the provider configuration | `string` | `null` | no |
265-
| <a name="input_root_block_device"></a> [root\_block\_device](#input\_root\_block\_device) | Customize details about the root block device of the instance. See Block Devices below for details | <pre>map(object({<br/> delete_on_termination = optional(bool)<br/> encrypted = optional(bool)<br/> iops = optional(number)<br/> kms_key_id = optional(string)<br/> tags = optional(map(string), {})<br/> throughput = optional(number)<br/> size = optional(number)<br/> type = optional(string)<br/> }))</pre> | `null` | no |
258+
| <a name="input_root_block_device"></a> [root\_block\_device](#input\_root\_block\_device) | Customize details about the root block device of the instance. See Block Devices below for details | <pre>object({<br/> delete_on_termination = optional(bool)<br/> encrypted = optional(bool)<br/> iops = optional(number)<br/> kms_key_id = optional(string)<br/> tags = optional(map(string), {})<br/> throughput = optional(number)<br/> size = optional(number)<br/> type = optional(string)<br/> })</pre> | `null` | no |
266259
| <a name="input_secondary_private_ips"></a> [secondary\_private\_ips](#input\_secondary\_private\_ips) | A list of secondary private IPv4 addresses to assign to the instance's primary network interface (eth0) in a VPC. Can only be assigned to the primary network interface (eth0) attached at instance creation, not a pre-existing network interface i.e. referenced in a `network_interface block` | `list(string)` | `null` | no |
267260
| <a name="input_security_group_description"></a> [security\_group\_description](#input\_security\_group\_description) | Description of the security group | `string` | `null` | no |
268-
| <a name="input_security_group_egress_rules"></a> [security\_group\_egress\_rules](#input\_security\_group\_egress\_rules) | Egress rules to add to the security group | <pre>map(object({<br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(number)<br/> ip_protocol = optional(string)<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> tags = optional(map(string), {})<br/> to_port = optional(number)<br/> }))</pre> | <pre>{<br/> "ipv4_default": {<br/> "cidr_ipv4": "0.0.0.0/0",<br/> "description": "Allow all IPv4 traffic",<br/> "ip_protocol": "-1"<br/> },<br/> "ipv6_default": {<br/> "cidr_ipv6": "::/0",<br/> "description": "Allow all IPv6 traffic",<br/> "ip_protocol": "-1"<br/> }<br/>}</pre> | no |
269-
| <a name="input_security_group_ingress_rules"></a> [security\_group\_ingress\_rules](#input\_security\_group\_ingress\_rules) | Egress rules to add to the security group | <pre>map(object({<br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(number)<br/> ip_protocol = optional(string)<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> tags = optional(map(string), {})<br/> to_port = optional(number)<br/> }))</pre> | `null` | no |
261+
| <a name="input_security_group_egress_rules"></a> [security\_group\_egress\_rules](#input\_security\_group\_egress\_rules) | Egress rules to add to the security group | <pre>map(object({<br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(number)<br/> ip_protocol = optional(string, "tcp")<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> tags = optional(map(string), {})<br/> to_port = optional(number)<br/> }))</pre> | <pre>{<br/> "ipv4_default": {<br/> "cidr_ipv4": "0.0.0.0/0",<br/> "description": "Allow all IPv4 traffic",<br/> "ip_protocol": "-1"<br/> },<br/> "ipv6_default": {<br/> "cidr_ipv6": "::/0",<br/> "description": "Allow all IPv6 traffic",<br/> "ip_protocol": "-1"<br/> }<br/>}</pre> | no |
262+
| <a name="input_security_group_ingress_rules"></a> [security\_group\_ingress\_rules](#input\_security\_group\_ingress\_rules) | Egress rules to add to the security group | <pre>map(object({<br/> cidr_ipv4 = optional(string)<br/> cidr_ipv6 = optional(string)<br/> description = optional(string)<br/> from_port = optional(number)<br/> ip_protocol = optional(string, "tcp")<br/> prefix_list_id = optional(string)<br/> referenced_security_group_id = optional(string)<br/> tags = optional(map(string), {})<br/> to_port = optional(number)<br/> }))</pre> | `null` | no |
270263
| <a name="input_security_group_name"></a> [security\_group\_name](#input\_security\_group\_name) | Name to use on security group created | `string` | `null` | no |
271264
| <a name="input_security_group_tags"></a> [security\_group\_tags](#input\_security\_group\_tags) | A map of additional tags to add to the security group created | `map(string)` | `{}` | no |
272265
| <a name="input_security_group_use_name_prefix"></a> [security\_group\_use\_name\_prefix](#input\_security\_group\_use\_name\_prefix) | Determines whether the security group name (`security_group_name` or `name`) is used as a prefix | `bool` | `true` | no |
273266
| <a name="input_security_group_vpc_id"></a> [security\_group\_vpc\_id](#input\_security\_group\_vpc\_id) | VPC ID to create the security group in. If not set, the security group will be created in the default VPC | `string` | `null` | no |
274267
| <a name="input_source_dest_check"></a> [source\_dest\_check](#input\_source\_dest\_check) | Controls if traffic is routed to the instance when the destination address does not match the instance. Used for NAT or VPNs | `bool` | `null` | no |
268+
| <a name="input_spot_instance_interruption_behavior"></a> [spot\_instance\_interruption\_behavior](#input\_spot\_instance\_interruption\_behavior) | Indicates Spot instance behavior when it is interrupted. Valid values are `terminate`, `stop`, or `hibernate` | `string` | `null` | no |
275269
| <a name="input_spot_launch_group"></a> [spot\_launch\_group](#input\_spot\_launch\_group) | A launch group is a group of spot instances that launch together and terminate together. If left empty instances are launched and terminated individually | `string` | `null` | no |
276270
| <a name="input_spot_price"></a> [spot\_price](#input\_spot\_price) | The maximum price to request on the spot market. Defaults to on-demand price | `string` | `null` | no |
277271
| <a name="input_spot_type"></a> [spot\_type](#input\_spot\_type) | If set to one-time, after the instance is terminated, the spot request will be closed. Default `persistent` | `string` | `null` | no |

UPGRADE-6.0.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# Upgrade from v5.x to v6.x
2+
3+
If you have any questions regarding this upgrade process, please consult the `examples` directory:
4+
5+
- [Complete](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/complete)
6+
7+
If you find a bug, please open an issue with supporting configuration to reproduce.
8+
9+
## List of backwards incompatible changes
10+
11+
- Terraform v1.10.0 is now minimum supported version
12+
- AWS provider v6.0.0 is now minimum supported version
13+
- The default value for `ami_ssm_parameter` was changed from `"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"` to `"/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64"`. AL2 is approaching end of life.
14+
15+
## Additional changes
16+
17+
### Added
18+
19+
- Support for creating a security group within the module; this is now the default behavior and can be disabled by setting `create_security_group = false`.
20+
- Support for `region` parameter to specify the AWS region for the resources created if different from the provider region.
21+
- Support for tagging spot instances
22+
23+
### Modified
24+
25+
- Variable definitions now contain detailed `object` types in place of the previously used `any` type.
26+
- Inline `ebs_block_device` argument has been removed in favor of `ebs_volumes` which is a map of EBS volumes created through `aws_ebs_volume` and `aws_ebs_volume_attachment` resources. This provides the same API as before, but allows for more flexibility without generating diffs when adding or removing EBS volumes as well as unintended changes to the volumes.
27+
- Correct tag precedence ordering (least specific to most specific)
28+
29+
### Removed
30+
31+
- The `volume-attachment` example has been removed since the module has been updated to use the corrected form of EBS volume creation and attachment (tl;dr - example is no longer useful).
32+
33+
### Variable and output changes
34+
35+
1. Removed variables:
36+
37+
- `cpu_core_count` - removed from provider `v6.x`
38+
- `cpu_threads_per_core` - removed from provider `v6.x`
39+
40+
2. Renamed variables:
41+
42+
- `ebs_block_device` -> `ebs_volumes`
43+
44+
3. Added variables:
45+
46+
- `region`
47+
- `enable_primary_ipv6`
48+
- `host_resource_group_arn`
49+
- `instance_market_options`
50+
- `placement_partition_number`
51+
- `create_security_group`
52+
- `security_group_name`
53+
- `security_group_use_name_prefix`
54+
- `security_group_description`
55+
- `security_group_vpc_id`
56+
- `security_group_tags`
57+
- `security_group_egress_rules`
58+
- `security_group_ingress_rules`
59+
60+
4. Removed outputs:
61+
62+
- None
63+
64+
5. Renamed outputs:
65+
66+
- None
67+
68+
6. Added outputs:
69+
70+
- `ebs_volumes`
71+
72+
## Upgrade State Migrations
73+
74+
### Before 5.x Example
75+
76+
```hcl
77+
module "ec2_upgrade" {
78+
source = "terraform-aws-modules/ec2-instance/aws"
79+
version = "5.8.0"
80+
81+
# Truncated for brevity, only relevant module API changes are shown ...
82+
83+
root_block_device = [
84+
{
85+
encrypted = true
86+
volume_size = 50
87+
volume_type = "gp3"
88+
throughput = 200
89+
tags = {
90+
Name = "my-root-block"
91+
}
92+
},
93+
]
94+
95+
ebs_block_device = [
96+
{
97+
device_name = "/dev/sdf"
98+
encrypted = true
99+
volume_size = 5
100+
volume_type = "gp3"
101+
throughput = 200
102+
tags = {
103+
MountPoint = "/mnt/data"
104+
}
105+
}
106+
]
107+
108+
network_interface = [
109+
{
110+
device_index = 0
111+
network_interface_id = aws_network_interface.this.id
112+
delete_on_termination = false
113+
}
114+
]
115+
116+
tags = local.tags
117+
}
118+
```
119+
120+
### After 6.x Example
121+
122+
```hcl
123+
module "ec2_upgrade" {
124+
source = "terraform-aws-modules/ec2-instance/aws"
125+
version = "6.0.0"
126+
127+
# Truncated for brevity, only relevant module API changes are shown ...
128+
129+
# There can only be one root block device, so the wrapping list is removed
130+
root_block_device = {
131+
encrypted = true
132+
size = 50 # Was `volume_size`
133+
type = "gp3" # Was `volume_type`
134+
throughput = 200
135+
tags = {
136+
Name = "my-root-block"
137+
}
138+
}
139+
140+
# Now a map of EBS volumes is used instead of a list
141+
ebs_volumes = {
142+
# The device_name can be the key of the map, or set by `device_name` attribute
143+
"/dev/sdf" = {
144+
encrypted = true
145+
size = 5 # Was `volume_size`
146+
type = "gp3" # Was `volume_type`, `gp3` is now the default
147+
throughput = 200
148+
tags = {
149+
MountPoint = "/mnt/data"
150+
}
151+
}
152+
}
153+
154+
# Now a map of network interfaces is used instead of a list
155+
network_interface = {
156+
# The device_index can be the key of the map, or set by `device_index` attribute
157+
0 = {
158+
network_interface_id = aws_network_interface.this.id
159+
delete_on_termination = false
160+
}
161+
}
162+
163+
tags = local.tags
164+
}
165+
```
166+
167+
To migrate from the `v5.x` version to `v6.x` version example shown above, the following state move commands can be performed to maintain the current resources without modification:
168+
169+
> [!NOTE]
170+
> State move commands should only be required on instances that have additional EBS volumes attached to them.
171+
172+
```bash
173+
terraform state rm 'module.ec2_complete.aws_instance.this[0]'
174+
terraform import 'module.ec2_complete.aws_instance.this[0]' <INSTANCE_ID>
175+
176+
# Do the following for each additional EBS volume attached to the instance
177+
terraform import 'module.ec2_complete.aws_ebs_volume.this["/dev/sdf"]' <VOLUME_ID>
178+
terraform import 'module.ec2_complete.aws_volume_attachment.this["/dev/sdf"]' <DEVICE_NAME>:<VOLUME_ID>:<INSTANCE_ID>
179+
```
180+
181+
> [!TIP]
182+
> If you encounter a situation where Terraform wants to recreate the instance due to user data changes, you can set the `user_data_replace_on_change` variable to `false` to prevent this behavior.
183+
> This is related to https://github.com/hashicorp/terraform-provider-aws/issues/5011

examples/complete/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ Note that this example may create resources which can cost money. Run `terraform
3333
| Name | Source | Version |
3434
|------|--------|---------|
3535
| <a name="module_ec2_complete"></a> [ec2\_complete](#module\_ec2\_complete) | ../../ | n/a |
36-
| <a name="module_ec2_cpu_options"></a> [ec2\_cpu\_options](#module\_ec2\_cpu\_options) | ../../ | n/a |
3736
| <a name="module_ec2_disabled"></a> [ec2\_disabled](#module\_ec2\_disabled) | ../../ | n/a |
3837
| <a name="module_ec2_ignore_ami_changes"></a> [ec2\_ignore\_ami\_changes](#module\_ec2\_ignore\_ami\_changes) | ../../ | n/a |
3938
| <a name="module_ec2_metadata_options"></a> [ec2\_metadata\_options](#module\_ec2\_metadata\_options) | ../../ | n/a |

0 commit comments

Comments
 (0)