Commit 2d92dfef authored by Bryant Biggs's avatar Bryant Biggs Committed by GitHub

BREAKING CHANGE: update module to include latest features and remove use of...

BREAKING CHANGE: update module to include latest features and remove use of `count` for module `count`/`for_each` (#234)
parent 0817d0e9
......@@ -91,7 +91,7 @@ jobs:
- name: Install pre-commit dependencies
run: |
pip install pre-commit
curl -Lo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.13.0/terraform-docs-v0.13.0-$(uname)-amd64.tar.gz && tar -xzf terraform-docs.tar.gz && chmod +x terraform-docs && sudo mv terraform-docs /usr/bin/
curl -Lo ./terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.13.0/terraform-docs-v0.13.0-$(uname)-amd64.tar.gz && tar -xzf terraform-docs.tar.gz terraform-docs && chmod +x terraform-docs && sudo mv terraform-docs /usr/bin/
curl -L "$(curl -s https://api.github.com/repos/terraform-linters/tflint/releases/latest | grep -o -E "https://.+?_linux_amd64.zip")" > tflint.zip && unzip tflint.zip && rm tflint.zip && sudo mv tflint /usr/bin/
- name: Execute pre-commit
# Run all pre-commit checks on max version supported
......
......@@ -21,6 +21,6 @@ repos:
- '--args=--only=terraform_standard_module_structure'
- '--args=--only=terraform_workspace_remote'
- repo: git://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0
rev: v4.0.1
hooks:
- id: check-merge-conflict
This diff is collapsed.
# Upgrade from v2.x to v3.x
If you have any questions regarding this upgrade process, please consult the `examples` directory:
- [Complete](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/complete)
- [Volume Attachment](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/volume-attachment)
If you find a bug, please open an issue with supporting configuration to reproduce.
## List of backwards incompatible changes
- Terraform v0.13.1 is now minimum supported version to take advantage of `count` and `for_each` arguments at module level
### Variable and output changes
1. Removed variables:
- `instance_count`
- `subnet_ids` (only need to use `subnet_id` now)
- `private_ips` (only need to use `private_ip` now)
- `use_num_suffix`
- `num_suffix_format`
2. Renamed variables:
- `tags` -> `tags_all`
3. Removed outputs:
- `availability_zone`
- `placement_group`
- `key_name`
- `ipv6_addresses`
- `private_ip`
- `security_groups`
- `vpc_security_group_ids`
- `subnet_id`
- `credit_specification`
- `metadata_options`
- `root_block_device_volume_ids`
- `ebs_block_device_volume_ids`
- `volume_tags`
- `instance_count`
4. Renamed outputs:
:info: All outputs used to be lists, and are now singular outputs due to the removal of `count`
## Upgrade State Migrations
### Before 2.x Example
```hcl
module "ec2_upgrade" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "2.21.0"
instance_count = 3
name = local.name
ami = data.aws_ami.amazon_linux.id
instance_type = "c5.large"
subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true
tags = local.tags
}
```
### After 3.x Example
```hcl
locals {
num_suffix_format = "-%d"
multiple_instances = {
0 = {
num_suffix = 1
instance_type = "c5.large"
subnet_id = element(module.vpc.private_subnets, 0)
}
1 = {
num_suffix = 2
instance_type = "c5.large"
subnet_id = element(module.vpc.private_subnets, 1)
}
2 = {
num_suffix = 3
instance_type = "c5.large"
subnet_id = element(module.vpc.private_subnets, 2)
}
}
}
module "ec2_upgrade" {
source = "../../"
for_each = local.multiple_instances
name = format("%s${local.num_suffix_format}", local.name, each.value.num_suffix)
ami = data.aws_ami.amazon_linux.id
instance_type = each.value.instance_type
subnet_id = each.value.subnet_id
vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true
tags = local.tags
}
```
To migrate from the `v2.x` version to `v3.x` version example shown above, the following state move commands can be performed to maintain the current resources without modification:
```bash
terraform state mv 'module.ec2_upgrade.aws_instance.this[0]' 'module.ec2_upgrade["0"].aws_instance.this[0]'
terraform state mv 'module.ec2_upgrade.aws_instance.this[1]' 'module.ec2_upgrade["1"].aws_instance.this[0]'
terraform state mv 'module.ec2_upgrade.aws_instance.this[2]' 'module.ec2_upgrade["2"].aws_instance.this[0]'
```
:info: Notes
- In the `v2.x` example we use `subnet_ids` which is an array of subnets. These are mapped to the respective instance based on their index location; therefore in the `v3.x` example we are doing a similar index lookup to map back to the existing subnet used for that instance. This would also be the case for `private_ips`
- In the `v3.x` example we have shown how users can continue to use the same naming scheme that is currently in use by the `v2.x` module. By moving the `num_suffix_format` into the module name itself inside a format function, users can continue to customize the names generated in a similar manner as that of the `v2.x` module.
# Basic EC2 instance
Configuration in this directory creates EC2 instances with different sets of arguments (with Elastic IP, with network interface attached, with credit specifications).
## Usage
To run this example you need to execute:
```bash
$ terraform init
$ terraform plan
$ terraform apply
```
Note that this example may create resources which can cost money. Run `terraform destroy` when you don't need these resources.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.6 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.65 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.65 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_ec2"></a> [ec2](#module\_ec2) | ../../ | |
| <a name="module_ec2_optimize_cpu"></a> [ec2\_optimize\_cpu](#module\_ec2\_optimize\_cpu) | ../../ | |
| <a name="module_ec2_with_metadata_options"></a> [ec2\_with\_metadata\_options](#module\_ec2\_with\_metadata\_options) | ../../ | |
| <a name="module_ec2_with_network_interface"></a> [ec2\_with\_network\_interface](#module\_ec2\_with\_network\_interface) | ../../ | |
| <a name="module_ec2_with_t2_unlimited"></a> [ec2\_with\_t2\_unlimited](#module\_ec2\_with\_t2\_unlimited) | ../../ | |
| <a name="module_ec2_with_t3_unlimited"></a> [ec2\_with\_t3\_unlimited](#module\_ec2\_with\_t3\_unlimited) | ../../ | |
| <a name="module_ec2_zero"></a> [ec2\_zero](#module\_ec2\_zero) | ../../ | |
| <a name="module_security_group"></a> [security\_group](#module\_security\_group) | terraform-aws-modules/security-group/aws | ~> 4.0 |
## Resources
| Name | Type |
|------|------|
| [aws_eip.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eip) | resource |
| [aws_kms_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_network_interface.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_interface) | resource |
| [aws_placement_group.web](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/placement_group) | resource |
| [aws_ami.amazon_linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
| [aws_subnet_ids.all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet_ids) | data source |
| [aws_vpc.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |
## Inputs
No inputs.
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_credit_specification"></a> [credit\_specification](#output\_credit\_specification) | Credit specification of EC2 instance (empty list for not t2 instance types) |
| <a name="output_credit_specification_t2_unlimited"></a> [credit\_specification\_t2\_unlimited](#output\_credit\_specification\_t2\_unlimited) | Credit specification of t2-type EC2 instance |
| <a name="output_ebs_block_device_volume_ids"></a> [ebs\_block\_device\_volume\_ids](#output\_ebs\_block\_device\_volume\_ids) | List of volume IDs of EBS block devices of instances |
| <a name="output_ids"></a> [ids](#output\_ids) | List of IDs of instances |
| <a name="output_ids_t2"></a> [ids\_t2](#output\_ids\_t2) | List of IDs of t2-type instances |
| <a name="output_instance_id"></a> [instance\_id](#output\_instance\_id) | EC2 instance ID |
| <a name="output_instance_public_dns"></a> [instance\_public\_dns](#output\_instance\_public\_dns) | Public DNS name assigned to the EC2 instance |
| <a name="output_metadata_options"></a> [metadata\_options](#output\_metadata\_options) | Metadata options for the instance |
| <a name="output_metadata_options_custom"></a> [metadata\_options\_custom](#output\_metadata\_options\_custom) | Customized metadata options for the instance |
| <a name="output_placement_group"></a> [placement\_group](#output\_placement\_group) | List of placement group |
| <a name="output_public_dns"></a> [public\_dns](#output\_public\_dns) | List of public DNS names assigned to the instances |
| <a name="output_root_block_device_volume_ids"></a> [root\_block\_device\_volume\_ids](#output\_root\_block\_device\_volume\_ids) | List of volume IDs of root block devices of instances |
| <a name="output_t2_instance_id"></a> [t2\_instance\_id](#output\_t2\_instance\_id) | EC2 instance ID |
| <a name="output_tags"></a> [tags](#output\_tags) | List of tags |
| <a name="output_vpc_security_group_ids"></a> [vpc\_security\_group\_ids](#output\_vpc\_security\_group\_ids) | List of VPC security group ids assigned to the instances |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
output "ids" {
description = "List of IDs of instances"
value = module.ec2.id
}
output "ids_t2" {
description = "List of IDs of t2-type instances"
value = module.ec2_with_t2_unlimited.id
}
output "public_dns" {
description = "List of public DNS names assigned to the instances"
value = module.ec2.public_dns
}
output "vpc_security_group_ids" {
description = "List of VPC security group ids assigned to the instances"
value = module.ec2.vpc_security_group_ids
}
output "root_block_device_volume_ids" {
description = "List of volume IDs of root block devices of instances"
value = module.ec2.root_block_device_volume_ids
}
output "ebs_block_device_volume_ids" {
description = "List of volume IDs of EBS block devices of instances"
value = module.ec2.ebs_block_device_volume_ids
}
output "tags" {
description = "List of tags"
value = module.ec2.tags
}
output "placement_group" {
description = "List of placement group"
value = module.ec2.placement_group
}
output "instance_id" {
description = "EC2 instance ID"
value = module.ec2.id[0]
}
output "t2_instance_id" {
description = "EC2 instance ID"
value = module.ec2_with_t2_unlimited.id[0]
}
output "instance_public_dns" {
description = "Public DNS name assigned to the EC2 instance"
value = module.ec2.public_dns[0]
}
output "credit_specification" {
description = "Credit specification of EC2 instance (empty list for not t2 instance types)"
value = module.ec2.credit_specification
}
output "credit_specification_t2_unlimited" {
description = "Credit specification of t2-type EC2 instance"
value = module.ec2_with_t2_unlimited.credit_specification
}
output "metadata_options" {
description = "Metadata options for the instance"
value = module.ec2.metadata_options
}
output "metadata_options_custom" {
description = "Customized metadata options for the instance"
value = module.ec2_with_metadata_options.metadata_options
}
terraform {
required_version = ">= 0.12.6"
required_providers {
aws = ">= 2.65"
}
}
# Complete EC2 instance
Configuration in this directory creates EC2 instances with different sets of arguments (with Elastic IP, with network interface attached, with credit specifications).
## Usage
To run this example you need to execute:
```bash
$ terraform init
$ terraform plan
$ terraform apply
```
Note that this example may create resources which can cost money. Run `terraform destroy` when you don't need these resources.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.51 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.51 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| <a name="module_ec2_complete"></a> [ec2\_complete](#module\_ec2\_complete) | ../../ | |
| <a name="module_ec2_disabled"></a> [ec2\_disabled](#module\_ec2\_disabled) | ../../ | |
| <a name="module_ec2_metadata_options"></a> [ec2\_metadata\_options](#module\_ec2\_metadata\_options) | ../../ | |
| <a name="module_ec2_multiple"></a> [ec2\_multiple](#module\_ec2\_multiple) | ../../ | |
| <a name="module_ec2_network_interface"></a> [ec2\_network\_interface](#module\_ec2\_network\_interface) | ../../ | |
| <a name="module_ec2_t2_unlimited"></a> [ec2\_t2\_unlimited](#module\_ec2\_t2\_unlimited) | ../../ | |
| <a name="module_ec2_t3_unlimited"></a> [ec2\_t3\_unlimited](#module\_ec2\_t3\_unlimited) | ../../ | |
| <a name="module_security_group"></a> [security\_group](#module\_security\_group) | terraform-aws-modules/security-group/aws | ~> 4.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 |
## Resources
| Name | Type |
|------|------|
| [aws_kms_key.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_network_interface.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/network_interface) | resource |
| [aws_placement_group.web](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/placement_group) | resource |
| [aws_ami.amazon_linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
## Inputs
No inputs.
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_ec2_complete_arn"></a> [ec2\_complete\_arn](#output\_ec2\_complete\_arn) | The ARN of the instance |
| <a name="output_ec2_complete_capacity_reservation_specification"></a> [ec2\_complete\_capacity\_reservation\_specification](#output\_ec2\_complete\_capacity\_reservation\_specification) | Capacity reservation specification of the instance |
| <a name="output_ec2_complete_id"></a> [ec2\_complete\_id](#output\_ec2\_complete\_id) | The ID of the instance |
| <a name="output_ec2_complete_instance_state"></a> [ec2\_complete\_instance\_state](#output\_ec2\_complete\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` |
| <a name="output_ec2_complete_primary_network_interface_id"></a> [ec2\_complete\_primary\_network\_interface\_id](#output\_ec2\_complete\_primary\_network\_interface\_id) | The ID of the instance's primary network interface |
| <a name="output_ec2_complete_private_dns"></a> [ec2\_complete\_private\_dns](#output\_ec2\_complete\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC |
| <a name="output_ec2_complete_public_dns"></a> [ec2\_complete\_public\_dns](#output\_ec2\_complete\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC |
| <a name="output_ec2_complete_public_ip"></a> [ec2\_complete\_public\_ip](#output\_ec2\_complete\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached |
| <a name="output_ec2_complete_tags_all"></a> [ec2\_complete\_tags\_all](#output\_ec2\_complete\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block |
| <a name="output_ec2_multiple"></a> [ec2\_multiple](#output\_ec2\_multiple) | The full output of the `ec2_module` module |
| <a name="output_ec2_t2_unlimited_arn"></a> [ec2\_t2\_unlimited\_arn](#output\_ec2\_t2\_unlimited\_arn) | The ARN of the instance |
| <a name="output_ec2_t2_unlimited_capacity_reservation_specification"></a> [ec2\_t2\_unlimited\_capacity\_reservation\_specification](#output\_ec2\_t2\_unlimited\_capacity\_reservation\_specification) | Capacity reservation specification of the instance |
| <a name="output_ec2_t2_unlimited_id"></a> [ec2\_t2\_unlimited\_id](#output\_ec2\_t2\_unlimited\_id) | The ID of the instance |
| <a name="output_ec2_t2_unlimited_instance_state"></a> [ec2\_t2\_unlimited\_instance\_state](#output\_ec2\_t2\_unlimited\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` |
| <a name="output_ec2_t2_unlimited_primary_network_interface_id"></a> [ec2\_t2\_unlimited\_primary\_network\_interface\_id](#output\_ec2\_t2\_unlimited\_primary\_network\_interface\_id) | The ID of the instance's primary network interface |
| <a name="output_ec2_t2_unlimited_private_dns"></a> [ec2\_t2\_unlimited\_private\_dns](#output\_ec2\_t2\_unlimited\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC |
| <a name="output_ec2_t2_unlimited_public_dns"></a> [ec2\_t2\_unlimited\_public\_dns](#output\_ec2\_t2\_unlimited\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC |
| <a name="output_ec2_t2_unlimited_public_ip"></a> [ec2\_t2\_unlimited\_public\_ip](#output\_ec2\_t2\_unlimited\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached |
| <a name="output_ec2_t2_unlimited_tags_all"></a> [ec2\_t2\_unlimited\_tags\_all](#output\_ec2\_t2\_unlimited\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block |
| <a name="output_ec2_t3_unlimited_arn"></a> [ec2\_t3\_unlimited\_arn](#output\_ec2\_t3\_unlimited\_arn) | The ARN of the instance |
| <a name="output_ec2_t3_unlimited_capacity_reservation_specification"></a> [ec2\_t3\_unlimited\_capacity\_reservation\_specification](#output\_ec2\_t3\_unlimited\_capacity\_reservation\_specification) | Capacity reservation specification of the instance |
| <a name="output_ec2_t3_unlimited_id"></a> [ec2\_t3\_unlimited\_id](#output\_ec2\_t3\_unlimited\_id) | The ID of the instance |
| <a name="output_ec2_t3_unlimited_instance_state"></a> [ec2\_t3\_unlimited\_instance\_state](#output\_ec2\_t3\_unlimited\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` |
| <a name="output_ec2_t3_unlimited_primary_network_interface_id"></a> [ec2\_t3\_unlimited\_primary\_network\_interface\_id](#output\_ec2\_t3\_unlimited\_primary\_network\_interface\_id) | The ID of the instance's primary network interface |
| <a name="output_ec2_t3_unlimited_private_dns"></a> [ec2\_t3\_unlimited\_private\_dns](#output\_ec2\_t3\_unlimited\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC |
| <a name="output_ec2_t3_unlimited_public_dns"></a> [ec2\_t3\_unlimited\_public\_dns](#output\_ec2\_t3\_unlimited\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC |
| <a name="output_ec2_t3_unlimited_public_ip"></a> [ec2\_t3\_unlimited\_public\_ip](#output\_ec2\_t3\_unlimited\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached |
| <a name="output_ec2_t3_unlimited_tags_all"></a> [ec2\_t3\_unlimited\_tags\_all](#output\_ec2\_t3\_unlimited\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
# EC2 Complete
output "ec2_complete_id" {
description = "The ID of the instance"
value = module.ec2_complete.id
}
output "ec2_complete_arn" {
description = "The ARN of the instance"
value = module.ec2_complete.arn
}
output "ec2_complete_capacity_reservation_specification" {
description = "Capacity reservation specification of the instance"
value = module.ec2_complete.capacity_reservation_specification
}
output "ec2_complete_instance_state" {
description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`"
value = module.ec2_complete.instance_state
}
output "ec2_complete_primary_network_interface_id" {
description = "The ID of the instance's primary network interface"
value = module.ec2_complete.primary_network_interface_id
}
output "ec2_complete_private_dns" {
description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
value = module.ec2_complete.private_dns
}
output "ec2_complete_public_dns" {
description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
value = module.ec2_complete.public_dns
}
output "ec2_complete_public_ip" {
description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached"
value = module.ec2_complete.public_ip
}
output "ec2_complete_tags_all" {
description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block"
value = module.ec2_complete.tags_all
}
# EC2 T2 Unlimited
output "ec2_t2_unlimited_id" {
description = "The ID of the instance"
value = module.ec2_t2_unlimited.id
}
output "ec2_t2_unlimited_arn" {
description = "The ARN of the instance"
value = module.ec2_t2_unlimited.arn
}
output "ec2_t2_unlimited_capacity_reservation_specification" {
description = "Capacity reservation specification of the instance"
value = module.ec2_t2_unlimited.capacity_reservation_specification
}
output "ec2_t2_unlimited_instance_state" {
description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`"
value = module.ec2_t2_unlimited.instance_state
}
output "ec2_t2_unlimited_primary_network_interface_id" {
description = "The ID of the instance's primary network interface"
value = module.ec2_t2_unlimited.primary_network_interface_id
}
output "ec2_t2_unlimited_private_dns" {
description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
value = module.ec2_t2_unlimited.private_dns
}
output "ec2_t2_unlimited_public_dns" {
description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
value = module.ec2_t2_unlimited.public_dns
}
output "ec2_t2_unlimited_public_ip" {
description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached"
value = module.ec2_t2_unlimited.public_ip
}
output "ec2_t2_unlimited_tags_all" {
description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block"
value = module.ec2_t2_unlimited.tags_all
}
# EC2 T3 Unlimited
output "ec2_t3_unlimited_id" {
description = "The ID of the instance"
value = module.ec2_t3_unlimited.id
}
output "ec2_t3_unlimited_arn" {
description = "The ARN of the instance"
value = module.ec2_t3_unlimited.arn
}
output "ec2_t3_unlimited_capacity_reservation_specification" {
description = "Capacity reservation specification of the instance"
value = module.ec2_t3_unlimited.capacity_reservation_specification
}
output "ec2_t3_unlimited_instance_state" {
description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`"
value = module.ec2_t3_unlimited.instance_state
}
output "ec2_t3_unlimited_primary_network_interface_id" {
description = "The ID of the instance's primary network interface"
value = module.ec2_t3_unlimited.primary_network_interface_id
}
output "ec2_t3_unlimited_private_dns" {
description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
value = module.ec2_t3_unlimited.private_dns
}
output "ec2_t3_unlimited_public_dns" {
description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
value = module.ec2_t3_unlimited.public_dns
}
output "ec2_t3_unlimited_public_ip" {
description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached"
value = module.ec2_t3_unlimited.public_ip
}
output "ec2_t3_unlimited_tags_all" {
description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block"
value = module.ec2_t3_unlimited.tags_all
}
# EC2 Multiple
output "ec2_multiple" {
description = "The full output of the `ec2_module` module"
value = module.ec2_multiple
}
terraform {
required_version = ">= 0.13.1"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 3.51"
}
}
}
......@@ -2,8 +2,6 @@
Configuration in this directory creates EC2 instances, EBS volume and attach it together.
Unspecified arguments for security group id and subnet are inherited from the default VPC.
This example outputs instance id and EBS volume id.
## Usage
......@@ -23,14 +21,14 @@ Note that this example may create resources which can cost money. Run `terraform
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.6 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.65 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.51 |
## Providers
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.65 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.51 |
## Modules
......@@ -38,6 +36,7 @@ Note that this example may create resources which can cost money. Run `terraform
|------|--------|---------|
| <a name="module_ec2"></a> [ec2](#module\_ec2) | ../../ | |
| <a name="module_security_group"></a> [security\_group](#module\_security\_group) | terraform-aws-modules/security-group/aws | ~> 4.0 |
| <a name="module_vpc"></a> [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 3.0 |
## Resources
......@@ -46,20 +45,22 @@ Note that this example may create resources which can cost money. Run `terraform
| [aws_ebs_volume.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ebs_volume) | resource |
| [aws_volume_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/volume_attachment) | resource |
| [aws_ami.amazon_linux](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source |
| [aws_subnet_ids.all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/subnet_ids) | data source |
| [aws_vpc.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_instances_number"></a> [instances\_number](#input\_instances\_number) | NUmber of instances | `number` | `1` | no |
No inputs.
## Outputs
| Name | Description |
|------|-------------|
| <a name="output_ebs_volume_attachment_id"></a> [ebs\_volume\_attachment\_id](#output\_ebs\_volume\_attachment\_id) | The volume ID |
| <a name="output_ebs_volume_attachment_instance_id"></a> [ebs\_volume\_attachment\_instance\_id](#output\_ebs\_volume\_attachment\_instance\_id) | The instance ID |
| <a name="output_instances_public_ips"></a> [instances\_public\_ips](#output\_instances\_public\_ips) | Public IPs assigned to the EC2 instance |
| <a name="output_ec2_arn"></a> [ec2\_arn](#output\_ec2\_arn) | The ARN of the instance |
| <a name="output_ec2_capacity_reservation_specification"></a> [ec2\_capacity\_reservation\_specification](#output\_ec2\_capacity\_reservation\_specification) | Capacity reservation specification of the instance |
| <a name="output_ec2_id"></a> [ec2\_id](#output\_ec2\_id) | The ID of the instance |
| <a name="output_ec2_instance_state"></a> [ec2\_instance\_state](#output\_ec2\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` |
| <a name="output_ec2_primary_network_interface_id"></a> [ec2\_primary\_network\_interface\_id](#output\_ec2\_primary\_network\_interface\_id) | The ID of the instance's primary network interface |
| <a name="output_ec2_private_dns"></a> [ec2\_private\_dns](#output\_ec2\_private\_dns) | The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC |
| <a name="output_ec2_public_dns"></a> [ec2\_public\_dns](#output\_ec2\_public\_dns) | The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC |
| <a name="output_ec2_public_ip"></a> [ec2\_public\_ip](#output\_ec2\_public\_ip) | The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws\_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached |
| <a name="output_ec2_tags_all"></a> [ec2\_tags\_all](#output\_ec2\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
provider "aws" {
region = "eu-west-1"
region = local.region
}
##################################################################
# Data sources to get VPC, subnet, security group and AMI details
##################################################################
data "aws_vpc" "default" {
default = true
locals {
availability_zone = "${local.region}a"
name = "example-ec2-volume-attachment"
region = "eu-west-1"
tags = {
Owner = "user"
Environment = "dev"
}
}
data "aws_subnet_ids" "all" {
vpc_id = data.aws_vpc.default.id
}
################################################################################
# Supporting Resources
################################################################################
data "aws_ami" "amazon_linux" {
most_recent = true
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 3.0"
owners = ["amazon"]
name = local.name
cidr = "10.99.0.0/18"
filter {
name = "name"
azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
public_subnets = ["10.99.0.0/24", "10.99.1.0/24", "10.99.2.0/24"]
private_subnets = ["10.99.3.0/24", "10.99.4.0/24", "10.99.5.0/24"]
database_subnets = ["10.99.7.0/24", "10.99.8.0/24", "10.99.9.0/24"]
values = [
"amzn-ami-hvm-*-x86_64-gp2",
]
}
tags = local.tags
}
filter {
name = "owner-alias"
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
values = [
"amazon",
]
filter {
name = "name"
values = ["amzn-ami-hvm-*-x86_64-gp2"]
}
}
......@@ -39,39 +45,45 @@ module "security_group" {
source = "terraform-aws-modules/security-group/aws"
version = "~> 4.0"
name = "example"
name = local.name
description = "Security group for example usage with EC2 instance"
vpc_id = data.aws_vpc.default.id
vpc_id = module.vpc.vpc_id
ingress_cidr_blocks = ["0.0.0.0/0"]
ingress_rules = ["http-80-tcp", "all-icmp"]
egress_rules = ["all-all"]
tags = local.tags
}
################################################################################
# EC2 Module
################################################################################
module "ec2" {
source = "../../"
instance_count = var.instances_number
name = local.name
name = "example-with-ebs"
ami = data.aws_ami.amazon_linux.id
instance_type = "c5.large"
subnet_id = tolist(data.aws_subnet_ids.all.ids)[0]
availability_zone = local.availability_zone
subnet_id = element(module.vpc.private_subnets, 0)
vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true
tags = local.tags
}
resource "aws_volume_attachment" "this" {
count = var.instances_number
device_name = "/dev/sdh"
volume_id = aws_ebs_volume.this[count.index].id
instance_id = module.ec2.id[count.index]
volume_id = aws_ebs_volume.this.id
instance_id = module.ec2.id
}
resource "aws_ebs_volume" "this" {
count = var.instances_number
availability_zone = module.ec2.availability_zone[count.index]
availability_zone = local.availability_zone
size = 1
tags = local.tags
}
output "instances_public_ips" {
description = "Public IPs assigned to the EC2 instance"
value = module.ec2.public_ip
# EC2
output "ec2_id" {
description = "The ID of the instance"
value = module.ec2.id
}
output "ec2_arn" {
description = "The ARN of the instance"
value = module.ec2.arn
}
output "ec2_capacity_reservation_specification" {
description = "Capacity reservation specification of the instance"
value = module.ec2.capacity_reservation_specification
}
output "ec2_instance_state" {
description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`"
value = module.ec2.instance_state
}
output "ebs_volume_attachment_id" {
description = "The volume ID"
value = aws_volume_attachment.this.*.volume_id
output "ec2_primary_network_interface_id" {
description = "The ID of the instance's primary network interface"
value = module.ec2.primary_network_interface_id
}
output "ebs_volume_attachment_instance_id" {
description = "The instance ID"
value = aws_volume_attachment.this.*.instance_id
output "ec2_private_dns" {
description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
value = module.ec2.private_dns
}
output "ec2_public_dns" {
description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
value = module.ec2.public_dns
}
output "ec2_public_ip" {
description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached"
value = module.ec2.public_ip
}
output "ec2_tags_all" {
description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block"
value = module.ec2.tags_all
}
variable "instances_number" {
description = "NUmber of instances"
type = number
default = 1
}
terraform {
required_version = ">= 0.12.6"
required_version = ">= 0.13.1"
required_providers {
aws = ">= 2.65"
aws = {
source = "hashicorp/aws"
version = ">= 3.51"
}
}
}
......@@ -3,29 +3,47 @@ locals {
}
resource "aws_instance" "this" {
count = var.instance_count
ami = var.ami
instance_type = var.instance_type
user_data = var.user_data
user_data_base64 = var.user_data_base64
subnet_id = length(var.network_interface) > 0 ? null : element(
distinct(compact(concat([var.subnet_id], var.subnet_ids))),
count.index,
)
key_name = var.key_name
monitoring = var.monitoring
get_password_data = var.get_password_data
count = var.create ? 1 : 0
ami = var.ami
instance_type = var.instance_type
cpu_core_count = var.cpu_core_count
cpu_threads_per_core = var.cpu_threads_per_core
user_data = var.user_data
user_data_base64 = var.user_data_base64
hibernation = var.hibernation
availability_zone = var.availability_zone
subnet_id = var.subnet_id
vpc_security_group_ids = var.vpc_security_group_ids
iam_instance_profile = var.iam_instance_profile
key_name = var.key_name
monitoring = var.monitoring
get_password_data = var.get_password_data
iam_instance_profile = var.iam_instance_profile
associate_public_ip_address = var.associate_public_ip_address
private_ip = length(var.private_ips) > 0 ? element(var.private_ips, count.index) : var.private_ip
private_ip = var.private_ip
secondary_private_ips = var.secondary_private_ips
ipv6_address_count = var.ipv6_address_count
ipv6_addresses = var.ipv6_addresses
ebs_optimized = var.ebs_optimized
dynamic "capacity_reservation_specification" {
for_each = var.capacity_reservation_specification != null ? [var.capacity_reservation_specification] : []
content {
capacity_reservation_preference = lookup(capacity_reservation_specification.value, "capacity_reservation_preference", null)
dynamic "capacity_reservation_target" {
for_each = lookup(capacity_reservation_specification.value, "capacity_reservation_target", [])
content {
capacity_reservation_id = lookup(capacity_reservation_target.value, "capacity_reservation_id", null)
}
}
}
}
dynamic "root_block_device" {
for_each = var.root_block_device
content {
......@@ -65,7 +83,7 @@ resource "aws_instance" "this" {
}
dynamic "metadata_options" {
for_each = length(keys(var.metadata_options)) == 0 ? [] : [var.metadata_options]
for_each = var.metadata_options != null ? [var.metadata_options] : []
content {
http_endpoint = lookup(metadata_options.value, "http_endpoint", "enabled")
http_tokens = lookup(metadata_options.value, "http_tokens", "optional")
......@@ -82,29 +100,36 @@ resource "aws_instance" "this" {
}
}
dynamic "launch_template" {
for_each = var.launch_template != null ? [var.launch_template] : []
content {
id = lookup(var.launch_template, "id", null)
name = lookup(var.launch_template, "name", null)
version = lookup(var.launch_template, "version", null)
}
}
enclave_options {
enabled = var.enclave_options_enabled
}
source_dest_check = length(var.network_interface) > 0 ? null : var.source_dest_check
disable_api_termination = var.disable_api_termination
instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior
placement_group = var.placement_group
tenancy = var.tenancy
cpu_core_count = var.cpu_core_count
cpu_threads_per_core = var.cpu_threads_per_core
tags = merge(
{
"Name" = var.instance_count > 1 || var.use_num_suffix ? format("%s${var.num_suffix_format}", var.name, count.index + 1) : var.name
},
var.tags,
)
volume_tags = var.enable_volume_tags ? merge(
{
"Name" = var.instance_count > 1 || var.use_num_suffix ? format("%s${var.num_suffix_format}", var.name, count.index + 1) : var.name
},
var.volume_tags,
) : null
host_id = var.host_id
credit_specification {
cpu_credits = local.is_t_instance_type ? var.cpu_credits : null
}
}
\ No newline at end of file
timeouts {
create = lookup(var.timeouts, "create", null)
update = lookup(var.timeouts, "update", null)
delete = lookup(var.timeouts, "delete", null)
}
tags = merge({ "Name" = var.name }, var.tags)
volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null
}
output "id" {
description = "List of IDs of instances"
value = aws_instance.this.*.id
description = "The ID of the instance"
value = element(concat(aws_instance.this.*.id, [""]), 0)
}
output "arn" {
description = "List of ARNs of instances"
value = aws_instance.this.*.arn
description = "The ARN of the instance"
value = element(concat(aws_instance.this.*.arn, [""]), 0)
}
output "availability_zone" {
description = "List of availability zones of instances"
value = aws_instance.this.*.availability_zone
output "capacity_reservation_specification" {
description = "Capacity reservation specification of the instance"
value = element(concat(aws_instance.this.*.capacity_reservation_specification, [""]), 0)
}
output "placement_group" {
description = "List of placement groups of instances"
value = aws_instance.this.*.placement_group
output "instance_state" {
description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`"
value = element(concat(aws_instance.this.*.instance_state, [""]), 0)
}
output "key_name" {
description = "List of key names of instances"
value = aws_instance.this.*.key_name
output "outpost_arn" {
description = "The ARN of the Outpost the instance is assigned to"
value = element(concat(aws_instance.this.*.outpost_arn, [""]), 0)
}
output "password_data" {
description = "List of Base-64 encoded encrypted password data for the instance"
value = aws_instance.this.*.password_data
}
output "public_dns" {
description = "List of public DNS names assigned to the instances. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
value = aws_instance.this.*.public_dns
}
output "public_ip" {
description = "List of public IP addresses assigned to the instances, if applicable"
value = aws_instance.this.*.public_ip
}
output "ipv6_addresses" {
description = "List of assigned IPv6 addresses of instances"
value = aws_instance.this.*.ipv6_addresses
description = "Base-64 encoded encrypted password data for the instance. Useful for getting the administrator password for instances running Microsoft Windows. This attribute is only exported if `get_password_data` is true"
value = element(concat(aws_instance.this.*.password_data, [""]), 0)
}
output "primary_network_interface_id" {
description = "List of IDs of the primary network interface of instances"
value = aws_instance.this.*.primary_network_interface_id
description = "The ID of the instance's primary network interface"
value = element(concat(aws_instance.this.*.primary_network_interface_id, [""]), 0)
}
output "private_dns" {
description = "List of private DNS names assigned to the instances. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
value = aws_instance.this.*.private_dns
}
output "private_ip" {
description = "List of private IP addresses assigned to the instances"
value = aws_instance.this.*.private_ip
}
output "security_groups" {
description = "List of associated security groups of instances"
value = aws_instance.this.*.security_groups
}
output "vpc_security_group_ids" {
description = "List of associated security groups of instances, if running in non-default VPC"
value = aws_instance.this.*.vpc_security_group_ids
description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
value = element(concat(aws_instance.this.*.private_dns, [""]), 0)
}
output "subnet_id" {
description = "List of IDs of VPC subnets of instances"
value = aws_instance.this.*.subnet_id
}
output "credit_specification" {
description = "List of credit specification of instances"
value = aws_instance.this.*.credit_specification
}
output "metadata_options" {
description = "List of metadata options of instances"
value = aws_instance.this.*.metadata_options
}
output "instance_state" {
description = "List of instance states of instances"
value = aws_instance.this.*.instance_state
}
output "root_block_device_volume_ids" {
description = "List of volume IDs of root block devices of instances"
value = [for device in aws_instance.this.*.root_block_device : device.*.volume_id]
}
output "ebs_block_device_volume_ids" {
description = "List of volume IDs of EBS block devices of instances"
value = [for device in aws_instance.this.*.ebs_block_device : device.*.volume_id]
}
output "tags" {
description = "List of tags of instances"
value = aws_instance.this.*.tags
output "public_dns" {
description = "The public DNS name assigned to the instance. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
value = element(concat(aws_instance.this.*.public_dns, [""]), 0)
}
output "volume_tags" {
description = "List of tags of volumes of instances"
value = aws_instance.this.*.volume_tags
output "public_ip" {
description = "The public IP address assigned to the instance, if applicable. NOTE: If you are using an aws_eip with your instance, you should refer to the EIP's address directly and not use `public_ip` as this field will change after the EIP is attached"
value = element(concat(aws_instance.this.*.public_ip, [""]), 0)
}
output "instance_count" {
description = "Number of instances to launch specified as argument to this module"
value = var.instance_count
output "tags_all" {
description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block"
value = element(concat(aws_instance.this.*.tags_all, [""]), 0)
}
This diff is collapsed.
terraform {
required_version = ">= 0.12.6"
required_version = ">= 0.13.1"
required_providers {
aws = ">= 3.24"
aws = {
source = "hashicorp/aws"
version = ">= 3.51"
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment