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: ...@@ -91,7 +91,7 @@ jobs:
- name: Install pre-commit dependencies - name: Install pre-commit dependencies
run: | run: |
pip install pre-commit 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/ 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 - name: Execute pre-commit
# Run all pre-commit checks on max version supported # Run all pre-commit checks on max version supported
......
...@@ -21,6 +21,6 @@ repos: ...@@ -21,6 +21,6 @@ repos:
- '--args=--only=terraform_standard_module_structure' - '--args=--only=terraform_standard_module_structure'
- '--args=--only=terraform_workspace_remote' - '--args=--only=terraform_workspace_remote'
- repo: git://github.com/pre-commit/pre-commit-hooks - repo: git://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0 rev: v4.0.1
hooks: hooks:
- id: check-merge-conflict - id: check-merge-conflict
# AWS EC2 Instance Terraform module # AWS EC2 Instance Terraform module
Terraform module which creates EC2 instance(s) on AWS. Terraform module which creates an EC2 instance on AWS.
## Usage ## Usage
### Single EC2 Instance
```hcl
module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws"
version = "~> 3.0"
name = "single-instance"
ami = "ami-ebd02392"
instance_type = "t2.micro"
key_name = "user1"
monitoring = true
vpc_security_group_ids = ["sg-12345678"]
subnet_id = "subnet-eddcdzz4"
tags = {
Terraform = "true"
Environment = "dev"
}
}
```
### Multiple EC2 Instance
```hcl ```hcl
module "ec2_cluster" { module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws" source = "terraform-aws-modules/ec2-instance/aws"
version = "~> 2.0" version = "~> 3.0"
for_each = toset(["one", "two", "three"])
name = "my-cluster" name = "instance-${each.key}"
instance_count = 5
ami = "ami-ebd02392" ami = "ami-ebd02392"
instance_type = "t2.micro" instance_type = "t2.micro"
...@@ -28,7 +54,7 @@ module "ec2_cluster" { ...@@ -28,7 +54,7 @@ module "ec2_cluster" {
## Examples ## Examples
- [Basic EC2 instance](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/basic) - [Complete EC2 instance](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/complete)
- [EC2 instance with EBS volume attachment](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/volume-attachment) - [EC2 instance with EBS volume attachment](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/volume-attachment)
## Make an encrypted AMI for use ## Make an encrypted AMI for use
...@@ -75,23 +101,22 @@ data "aws_ami" "ubuntu-xenial" { ...@@ -75,23 +101,22 @@ data "aws_ami" "ubuntu-xenial" {
## Notes ## Notes
- `network_interface` can't be specified together with `vpc_security_group_ids`, `associate_public_ip_address`, `subnet_id`. See [basic example](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/basic) for details. - `network_interface` can't be specified together with `vpc_security_group_ids`, `associate_public_ip_address`, `subnet_id`. See [complete example](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/complete) for details.
- Changes in `ebs_block_device` argument will be ignored. Use [aws_volume_attachment](https://www.terraform.io/docs/providers/aws/r/volume_attachment.html) resource to attach and detach volumes from AWS EC2 instances. See [this example](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/volume-attachment). - Changes in `ebs_block_device` argument will be ignored. Use [aws_volume_attachment](https://www.terraform.io/docs/providers/aws/r/volume_attachment.html) resource to attach and detach volumes from AWS EC2 instances. See [this example](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/volume-attachment).
- One of `subnet_id` or `subnet_ids` is required. If both are provided, the value of `subnet_id` is prepended to the value of `subnet_ids`.
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements ## Requirements
| Name | Version | | Name | Version |
|------|---------| |------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.6 | | <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.24 | | <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.51 |
## Providers ## Providers
| Name | Version | | Name | Version |
|------|---------| |------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.24 | | <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.51 |
## Modules ## Modules
...@@ -107,39 +132,43 @@ No modules. ...@@ -107,39 +132,43 @@ No modules.
| Name | Description | Type | Default | Required | | Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:| |------|-------------|------|---------|:--------:|
| <a name="input_ami"></a> [ami](#input\_ami) | ID of AMI to use for the instance | `string` | n/a | yes | | <a name="input_ami"></a> [ami](#input\_ami) | ID of AMI to use for the instance | `string` | `""` | no |
| <a name="input_associate_public_ip_address"></a> [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | If true, the EC2 instance will have associated public IP address | `bool` | `null` | no | | <a name="input_associate_public_ip_address"></a> [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Whether to associate a public IP address with an instance in a VPC | `bool` | `null` | no |
| <a name="input_availability_zone"></a> [availability\_zone](#input\_availability\_zone) | AZ to start the instance in | `string` | `null` | no |
| <a name="input_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#input\_capacity\_reservation\_specification) | Describes an instance's Capacity Reservation targeting option | `any` | `null` | no |
| <a name="input_cpu_core_count"></a> [cpu\_core\_count](#input\_cpu\_core\_count) | Sets the number of CPU cores for an instance. | `number` | `null` | no | | <a name="input_cpu_core_count"></a> [cpu\_core\_count](#input\_cpu\_core\_count) | Sets the number of CPU cores for an instance. | `number` | `null` | no |
| <a name="input_cpu_credits"></a> [cpu\_credits](#input\_cpu\_credits) | The credit option for CPU usage (unlimited or standard) | `string` | `"standard"` | no | | <a name="input_cpu_credits"></a> [cpu\_credits](#input\_cpu\_credits) | The credit option for CPU usage (unlimited or standard) | `string` | `null` | no |
| <a name="input_cpu_threads_per_core"></a> [cpu\_threads\_per\_core](#input\_cpu\_threads\_per\_core) | Sets the number of CPU threads per core for an instance (has no effect unless cpu\_core\_count is also set). | `number` | `null` | no | | <a name="input_cpu_threads_per_core"></a> [cpu\_threads\_per\_core](#input\_cpu\_threads\_per\_core) | Sets the number of CPU threads per core for an instance (has no effect unless cpu\_core\_count is also set). | `number` | `null` | no |
| <a name="input_disable_api_termination"></a> [disable\_api\_termination](#input\_disable\_api\_termination) | If true, enables EC2 Instance Termination Protection | `bool` | `false` | no | | <a name="input_create"></a> [create](#input\_create) | Whether to create an instance | `bool` | `true` | no |
| <a name="input_disable_api_termination"></a> [disable\_api\_termination](#input\_disable\_api\_termination) | If true, enables EC2 Instance Termination Protection | `bool` | `null` | no |
| <a name="input_ebs_block_device"></a> [ebs\_block\_device](#input\_ebs\_block\_device) | Additional EBS block devices to attach to the instance | `list(map(string))` | `[]` | no | | <a name="input_ebs_block_device"></a> [ebs\_block\_device](#input\_ebs\_block\_device) | Additional EBS block devices to attach to the instance | `list(map(string))` | `[]` | no |
| <a name="input_ebs_optimized"></a> [ebs\_optimized](#input\_ebs\_optimized) | If true, the launched EC2 instance will be EBS-optimized | `bool` | `false` | no | | <a name="input_ebs_optimized"></a> [ebs\_optimized](#input\_ebs\_optimized) | If true, the launched EC2 instance will be EBS-optimized | `bool` | `null` | no |
| <a name="input_enable_volume_tags"></a> [enable\_volume\_tags](#input\_enable\_volume\_tags) | Whether to enable volume tags (if enabled it conflicts with root\_block\_device tags) | `bool` | `true` | no | | <a name="input_enable_volume_tags"></a> [enable\_volume\_tags](#input\_enable\_volume\_tags) | Whether to enable volume tags (if enabled it conflicts with root\_block\_device tags) | `bool` | `true` | no |
| <a name="input_enclave_options_enabled"></a> [enclave\_options\_enabled](#input\_enclave\_options\_enabled) | Whether Nitro Enclaves will be enabled on the instance. Defaults to `false` | `bool` | `null` | no |
| <a name="input_ephemeral_block_device"></a> [ephemeral\_block\_device](#input\_ephemeral\_block\_device) | Customize Ephemeral (also known as Instance Store) volumes on the instance | `list(map(string))` | `[]` | no | | <a name="input_ephemeral_block_device"></a> [ephemeral\_block\_device](#input\_ephemeral\_block\_device) | Customize Ephemeral (also known as Instance Store) volumes on the instance | `list(map(string))` | `[]` | no |
| <a name="input_get_password_data"></a> [get\_password\_data](#input\_get\_password\_data) | If true, wait for password data to become available and retrieve it. | `bool` | `false` | no | | <a name="input_get_password_data"></a> [get\_password\_data](#input\_get\_password\_data) | If true, wait for password data to become available and retrieve it. | `bool` | `null` | no |
| <a name="input_iam_instance_profile"></a> [iam\_instance\_profile](#input\_iam\_instance\_profile) | The IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile. | `string` | `""` | no | | <a name="input_hibernation"></a> [hibernation](#input\_hibernation) | If true, the launched EC2 instance will support hibernation | `bool` | `null` | no |
| <a name="input_instance_count"></a> [instance\_count](#input\_instance\_count) | Number of instances to launch | `number` | `1` | no | | <a name="input_host_id"></a> [host\_id](#input\_host\_id) | ID of a dedicated host that the instance will be assigned to. Use when an instance is to be launched on a specific dedicated host | `string` | `null` | no |
| <a name="input_instance_initiated_shutdown_behavior"></a> [instance\_initiated\_shutdown\_behavior](#input\_instance\_initiated\_shutdown\_behavior) | Shutdown behavior for the instance | `string` | `""` | no | | <a name="input_iam_instance_profile"></a> [iam\_instance\_profile](#input\_iam\_instance\_profile) | IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile | `string` | `null` | no |
| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | The type of instance to start | `string` | n/a | yes | | <a name="input_instance_initiated_shutdown_behavior"></a> [instance\_initiated\_shutdown\_behavior](#input\_instance\_initiated\_shutdown\_behavior) | Shutdown behavior for the instance. Amazon defaults this to stop for EBS-backed instances and terminate for instance-store instances. Cannot be set on instance-store instance | `string` | `null` | no |
| <a name="input_ipv6_address_count"></a> [ipv6\_address\_count](#input\_ipv6\_address\_count) | A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet. | `number` | `null` | no | | <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | The type of instance to start | `string` | `"t3.micro"` | no |
| <a name="input_ipv6_address_count"></a> [ipv6\_address\_count](#input\_ipv6\_address\_count) | A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet | `number` | `null` | no |
| <a name="input_ipv6_addresses"></a> [ipv6\_addresses](#input\_ipv6\_addresses) | Specify one or more IPv6 addresses from the range of the subnet to associate with the primary network interface | `list(string)` | `null` | no | | <a name="input_ipv6_addresses"></a> [ipv6\_addresses](#input\_ipv6\_addresses) | Specify one or more IPv6 addresses from the range of the subnet to associate with the primary network interface | `list(string)` | `null` | no |
| <a name="input_key_name"></a> [key\_name](#input\_key\_name) | The key name to use for the instance | `string` | `""` | no | | <a name="input_key_name"></a> [key\_name](#input\_key\_name) | Key name of the Key Pair to use for the instance; which can be managed using the `aws_key_pair` resource | `string` | `null` | no |
| <a name="input_launch_template"></a> [launch\_template](#input\_launch\_template) | Specifies a Launch Template to configure the instance. Parameters configured on this resource will override the corresponding parameters in the Launch Template | `map(string)` | `null` | no |
| <a name="input_metadata_options"></a> [metadata\_options](#input\_metadata\_options) | Customize the metadata options of the instance | `map(string)` | `{}` | no | | <a name="input_metadata_options"></a> [metadata\_options](#input\_metadata\_options) | Customize the metadata options of the instance | `map(string)` | `{}` | no |
| <a name="input_monitoring"></a> [monitoring](#input\_monitoring) | If true, the launched EC2 instance will have detailed monitoring enabled | `bool` | `false` | no | | <a name="input_monitoring"></a> [monitoring](#input\_monitoring) | If true, the launched EC2 instance will have detailed monitoring enabled | `bool` | `false` | no |
| <a name="input_name"></a> [name](#input\_name) | Name to be used on all resources as prefix | `string` | n/a | yes | | <a name="input_name"></a> [name](#input\_name) | Name to be used on EC2 instance created | `string` | `""` | no |
| <a name="input_network_interface"></a> [network\_interface](#input\_network\_interface) | Customize network interfaces to be attached at instance boot time | `list(map(string))` | `[]` | no | | <a name="input_network_interface"></a> [network\_interface](#input\_network\_interface) | Customize network interfaces to be attached at instance boot time | `list(map(string))` | `[]` | no |
| <a name="input_num_suffix_format"></a> [num\_suffix\_format](#input\_num\_suffix\_format) | Numerical suffix format used as the volume and EC2 instance name suffix | `string` | `"-%d"` | no | | <a name="input_placement_group"></a> [placement\_group](#input\_placement\_group) | The Placement Group to start the instance in | `string` | `null` | no |
| <a name="input_placement_group"></a> [placement\_group](#input\_placement\_group) | The Placement Group to start the instance in | `string` | `""` | no |
| <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 | | <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 |
| <a name="input_private_ips"></a> [private\_ips](#input\_private\_ips) | A list of private IP address to associate with the instance in a VPC. Should match the number of instances. | `list(string)` | `[]` | no |
| <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 | `list(any)` | `[]` | no | | <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 | `list(any)` | `[]` | no |
| <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 |
| <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` | `true` | no | | <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` | `true` | no |
| <a name="input_subnet_id"></a> [subnet\_id](#input\_subnet\_id) | The VPC Subnet ID to launch in | `string` | `""` | no | | <a name="input_subnet_id"></a> [subnet\_id](#input\_subnet\_id) | The VPC Subnet ID to launch in | `string` | `null` | no |
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | A list of VPC Subnet IDs to launch in | `list(string)` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no | | <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resource | `map(string)` | `{}` | no |
| <a name="input_tenancy"></a> [tenancy](#input\_tenancy) | The tenancy of the instance (if the instance is running in a VPC). Available values: default, dedicated, host. | `string` | `"default"` | no | | <a name="input_tenancy"></a> [tenancy](#input\_tenancy) | The tenancy of the instance (if the instance is running in a VPC). Available values: default, dedicated, host. | `string` | `null` | no |
| <a name="input_use_num_suffix"></a> [use\_num\_suffix](#input\_use\_num\_suffix) | Always append numerical suffix to instance name, even if instance\_count is 1 | `bool` | `false` | no | | <a name="input_timeouts"></a> [timeouts](#input\_timeouts) | Define maximum timeout for creating, updating, and deleting EC2 instance resources | `map(string)` | `{}` | no |
| <a name="input_user_data"></a> [user\_data](#input\_user\_data) | The user data to provide when launching the instance. Do not pass gzip-compressed data via this argument; see user\_data\_base64 instead. | `string` | `null` | no | | <a name="input_user_data"></a> [user\_data](#input\_user\_data) | The user data to provide when launching the instance. Do not pass gzip-compressed data via this argument; see user\_data\_base64 instead. | `string` | `null` | no |
| <a name="input_user_data_base64"></a> [user\_data\_base64](#input\_user\_data\_base64) | Can be used instead of user\_data to pass base64-encoded binary data directly. Use this instead of user\_data whenever the value is not a valid UTF-8 string. For example, gzip-encoded user data must be base64-encoded and passed via this argument to avoid corruption. | `string` | `null` | no | | <a name="input_user_data_base64"></a> [user\_data\_base64](#input\_user\_data\_base64) | Can be used instead of user\_data to pass base64-encoded binary data directly. Use this instead of user\_data whenever the value is not a valid UTF-8 string. For example, gzip-encoded user data must be base64-encoded and passed via this argument to avoid corruption. | `string` | `null` | no |
| <a name="input_volume_tags"></a> [volume\_tags](#input\_volume\_tags) | A mapping of tags to assign to the devices created by the instance at launch time | `map(string)` | `{}` | no | | <a name="input_volume_tags"></a> [volume\_tags](#input\_volume\_tags) | A mapping of tags to assign to the devices created by the instance at launch time | `map(string)` | `{}` | no |
...@@ -149,29 +178,17 @@ No modules. ...@@ -149,29 +178,17 @@ No modules.
| Name | Description | | Name | Description |
|------|-------------| |------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | List of ARNs of instances | | <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the instance |
| <a name="output_availability_zone"></a> [availability\_zone](#output\_availability\_zone) | List of availability zones of instances | | <a name="output_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#output\_capacity\_reservation\_specification) | Capacity reservation specification of the instance |
| <a name="output_credit_specification"></a> [credit\_specification](#output\_credit\_specification) | List of credit specification of instances | | <a name="output_id"></a> [id](#output\_id) | The ID of the 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_instance_state"></a> [instance\_state](#output\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` |
| <a name="output_id"></a> [id](#output\_id) | List of IDs of instances | | <a name="output_outpost_arn"></a> [outpost\_arn](#output\_outpost\_arn) | The ARN of the Outpost the instance is assigned to |
| <a name="output_instance_count"></a> [instance\_count](#output\_instance\_count) | Number of instances to launch specified as argument to this module | | <a name="output_password_data"></a> [password\_data](#output\_password\_data) | 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 |
| <a name="output_instance_state"></a> [instance\_state](#output\_instance\_state) | List of instance states of instances | | <a name="output_primary_network_interface_id"></a> [primary\_network\_interface\_id](#output\_primary\_network\_interface\_id) | The ID of the instance's primary network interface |
| <a name="output_ipv6_addresses"></a> [ipv6\_addresses](#output\_ipv6\_addresses) | List of assigned IPv6 addresses of instances | | <a name="output_private_dns"></a> [private\_dns](#output\_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_key_name"></a> [key\_name](#output\_key\_name) | List of key names of instances | | <a name="output_public_dns"></a> [public\_dns](#output\_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_metadata_options"></a> [metadata\_options](#output\_metadata\_options) | List of metadata options of instances | | <a name="output_public_ip"></a> [public\_ip](#output\_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_password_data"></a> [password\_data](#output\_password\_data) | List of Base-64 encoded encrypted password data for the instance | | <a name="output_tags_all"></a> [tags\_all](#output\_tags\_all) | A map of tags assigned to the resource, including those inherited from the provider default\_tags configuration block |
| <a name="output_placement_group"></a> [placement\_group](#output\_placement\_group) | List of placement groups of instances |
| <a name="output_primary_network_interface_id"></a> [primary\_network\_interface\_id](#output\_primary\_network\_interface\_id) | List of IDs of the primary network interface of instances |
| <a name="output_private_dns"></a> [private\_dns](#output\_private\_dns) | 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 |
| <a name="output_private_ip"></a> [private\_ip](#output\_private\_ip) | List of private IP addresses assigned to the instances |
| <a name="output_public_dns"></a> [public\_dns](#output\_public\_dns) | 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 |
| <a name="output_public_ip"></a> [public\_ip](#output\_public\_ip) | List of public IP addresses assigned to the instances, if applicable |
| <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_security_groups"></a> [security\_groups](#output\_security\_groups) | List of associated security groups of instances |
| <a name="output_subnet_id"></a> [subnet\_id](#output\_subnet\_id) | List of IDs of VPC subnets of instances |
| <a name="output_tags"></a> [tags](#output\_tags) | List of tags of instances |
| <a name="output_volume_tags"></a> [volume\_tags](#output\_volume\_tags) | List of tags of volumes of instances |
| <a name="output_vpc_security_group_ids"></a> [vpc\_security\_group\_ids](#output\_vpc\_security\_group\_ids) | List of associated security groups of instances, if running in non-default VPC |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK --> <!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Authors ## Authors
......
# 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 -->
provider "aws" { provider "aws" {
region = "eu-west-1" region = local.region
} }
locals { locals {
user_data = <<EOF name = "example-ec2-complete"
#!/bin/bash region = "eu-west-1"
echo "Hello Terraform!"
EOF
}
################################################################## user_data = <<-EOT
# Data sources to get VPC, subnet, security group and AMI details #!/bin/bash
################################################################## echo "Hello Terraform!"
data "aws_vpc" "default" { EOT
default = true
}
data "aws_subnet_ids" "all" { tags = {
vpc_id = data.aws_vpc.default.id Owner = "user"
Environment = "dev"
}
} }
data "aws_ami" "amazon_linux" { ################################################################################
most_recent = true # Supporting Resources
################################################################################
owners = ["amazon"] module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 3.0"
filter { name = local.name
name = "name" cidr = "10.99.0.0/18"
values = [ azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
"amzn-ami-hvm-*-x86_64-gp2", 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"]
filter { tags = local.tags
name = "owner-alias" }
values = [ data "aws_ami" "amazon_linux" {
"amazon", most_recent = true
] owners = ["amazon"]
filter {
name = "name"
values = ["amzn-ami-hvm-*-x86_64-gp2"]
} }
} }
...@@ -46,22 +50,19 @@ module "security_group" { ...@@ -46,22 +50,19 @@ module "security_group" {
source = "terraform-aws-modules/security-group/aws" source = "terraform-aws-modules/security-group/aws"
version = "~> 4.0" version = "~> 4.0"
name = "example" name = local.name
description = "Security group for example usage with EC2 instance" 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_cidr_blocks = ["0.0.0.0/0"]
ingress_rules = ["http-80-tcp", "all-icmp"] ingress_rules = ["http-80-tcp", "all-icmp"]
egress_rules = ["all-all"] egress_rules = ["all-all"]
}
resource "aws_eip" "this" { tags = local.tags
vpc = true
instance = module.ec2.id[0]
} }
resource "aws_placement_group" "web" { resource "aws_placement_group" "web" {
name = "hunky-dory-pg" name = local.name
strategy = "cluster" strategy = "cluster"
} }
...@@ -69,33 +70,52 @@ resource "aws_kms_key" "this" { ...@@ -69,33 +70,52 @@ resource "aws_kms_key" "this" {
} }
resource "aws_network_interface" "this" { resource "aws_network_interface" "this" {
count = 1 subnet_id = element(module.vpc.private_subnets, 0)
}
################################################################################
# EC2 Module
################################################################################
subnet_id = tolist(data.aws_subnet_ids.all.ids)[count.index] module "ec2_disabled" {
source = "../../"
create = false
} }
module "ec2" { module "ec2_complete" {
source = "../../" source = "../../"
instance_count = 1 name = local.name
name = "example-normal" ami = data.aws_ami.amazon_linux.id
ami = data.aws_ami.amazon_linux.id instance_type = "c5.4xlarge"
instance_type = "c5.large" availability_zone = element(module.vpc.azs, 0)
subnet_id = tolist(data.aws_subnet_ids.all.ids)[0] subnet_id = element(module.vpc.private_subnets, 0)
# private_ips = ["172.31.32.5", "172.31.46.20"]
vpc_security_group_ids = [module.security_group.security_group_id] vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true
placement_group = aws_placement_group.web.id placement_group = aws_placement_group.web.id
associate_public_ip_address = true
# only one of these can be enabled at a time
hibernation = true
# enclave_options_enabled = true
user_data_base64 = base64encode(local.user_data) user_data_base64 = base64encode(local.user_data)
cpu_core_count = 2 # default 4
cpu_threads_per_core = 1 # default 2
capacity_reservation_specification = {
capacity_reservation_preference = "open"
}
enable_volume_tags = false enable_volume_tags = false
root_block_device = [ root_block_device = [
{ {
encrypted = true
volume_type = "gp3" volume_type = "gp3"
volume_size = 10
throughput = 200 throughput = 200
volume_size = 50
tags = { tags = {
Name = "my-root-block" Name = "my-root-block"
} }
...@@ -113,119 +133,134 @@ module "ec2" { ...@@ -113,119 +133,134 @@ module "ec2" {
} }
] ]
tags = { tags = local.tags
"Env" = "Private"
"Location" = "Secret"
}
} }
module "ec2_with_t2_unlimited" { module "ec2_network_interface" {
source = "../../" source = "../../"
instance_count = 1 name = "${local.name}-network-interface"
name = "example-t2-unlimited"
ami = data.aws_ami.amazon_linux.id ami = data.aws_ami.amazon_linux.id
instance_type = "t2.micro" instance_type = "c5.large"
cpu_credits = "unlimited"
subnet_id = tolist(data.aws_subnet_ids.all.ids)[0]
# private_ip = "172.31.32.10"
vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true
}
module "ec2_with_t3_unlimited" {
source = "../../"
instance_count = 1 network_interface = [
{
device_index = 0
network_interface_id = aws_network_interface.this.id
delete_on_termination = false
}
]
name = "example-t3-unlimited" tags = local.tags
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.large"
cpu_credits = "unlimited"
subnet_id = tolist(data.aws_subnet_ids.all.ids)[0]
vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true
} }
module "ec2_with_metadata_options" { module "ec2_metadata_options" {
source = "../../" source = "../../"
instance_count = 1 name = "${local.name}-metadata-options"
name = "example-metadata_options" ami = data.aws_ami.amazon_linux.id
ami = data.aws_ami.amazon_linux.id instance_type = "c5.4xlarge"
instance_type = "t2.small" subnet_id = element(module.vpc.private_subnets, 0)
subnet_id = tolist(data.aws_subnet_ids.all.ids)[0] vpc_security_group_ids = [module.security_group.security_group_id]
vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true
metadata_options = { metadata_options = {
http_endpoint = "enabled" http_endpoint = "enabled"
http_tokens = "required" http_tokens = "required"
http_put_response_hop_limit = 8 http_put_response_hop_limit = 8
} }
tags = local.tags
} }
module "ec2_with_network_interface" { module "ec2_t2_unlimited" {
source = "../../" source = "../../"
instance_count = 1 name = "${local.name}-t2-unlimited"
name = "example-network" ami = data.aws_ami.amazon_linux.id
ami = data.aws_ami.amazon_linux.id instance_type = "t2.micro"
instance_type = "c5.large" cpu_credits = "unlimited"
placement_group = aws_placement_group.web.id subnet_id = element(module.vpc.private_subnets, 0)
vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true
network_interface = [ tags = local.tags
{
device_index = 0
network_interface_id = aws_network_interface.this[0].id
delete_on_termination = false
}
]
} }
# This instance won't be created module "ec2_t3_unlimited" {
module "ec2_zero" {
source = "../../" source = "../../"
instance_count = 0 name = "${local.name}-t3-unlimited"
name = "example-zero" ami = data.aws_ami.amazon_linux.id
ami = data.aws_ami.amazon_linux.id instance_type = "t3.micro"
instance_type = "c5.large" cpu_credits = "unlimited"
subnet_id = tolist(data.aws_subnet_ids.all.ids)[0] subnet_id = element(module.vpc.private_subnets, 0)
vpc_security_group_ids = [module.security_group.security_group_id] vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true
tags = local.tags
} }
module "ec2_optimize_cpu" { ################################################################################
source = "../../" # EC2 Module - multiple instances with `for_each`
################################################################################
instance_count = 1 locals {
multiple_instances = {
one = {
instance_type = "t3.micro"
availability_zone = element(module.vpc.azs, 0)
subnet_id = element(module.vpc.private_subnets, 0)
root_block_device = [
{
encrypted = true
volume_type = "gp3"
throughput = 200
volume_size = 50
tags = {
Name = "my-root-block"
}
}
]
}
two = {
instance_type = "t3.small"
availability_zone = element(module.vpc.azs, 1)
subnet_id = element(module.vpc.private_subnets, 1)
root_block_device = [
{
encrypted = true
volume_type = "gp2"
volume_size = 50
}
]
}
three = {
instance_type = "t3.medium"
availability_zone = element(module.vpc.azs, 2)
subnet_id = element(module.vpc.private_subnets, 2)
}
}
}
name = "example-optimize-cpu" module "ec2_multiple" {
ami = data.aws_ami.amazon_linux.id source = "../../"
instance_type = "c4.2xlarge"
subnet_id = tolist(data.aws_subnet_ids.all.ids)[0]
vpc_security_group_ids = [module.security_group.security_group_id] for_each = local.multiple_instances
associate_public_ip_address = true
placement_group = aws_placement_group.web.id
user_data_base64 = base64encode(local.user_data) name = "${local.name}-multi-${each.key}"
root_block_device = [ ami = data.aws_ami.amazon_linux.id
{ instance_type = each.value.instance_type
volume_type = "gp2" availability_zone = each.value.availability_zone
volume_size = 10 subnet_id = each.value.subnet_id
}, vpc_security_group_ids = [module.security_group.security_group_id]
]
cpu_core_count = 2 # default 4
cpu_threads_per_core = 1 # default 2
tags = { enable_volume_tags = false
"Env" = "Private" root_block_device = lookup(each.value, "root_block_device", [])
"Location" = "Secret"
} tags = local.tags
} }
# 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 @@ ...@@ -2,8 +2,6 @@
Configuration in this directory creates EC2 instances, EBS volume and attach it together. 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. This example outputs instance id and EBS volume id.
## Usage ## Usage
...@@ -23,14 +21,14 @@ Note that this example may create resources which can cost money. Run `terraform ...@@ -23,14 +21,14 @@ Note that this example may create resources which can cost money. Run `terraform
| Name | Version | | Name | Version |
|------|---------| |------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12.6 | | <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.1 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 2.65 | | <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.51 |
## Providers ## Providers
| Name | Version | | Name | Version |
|------|---------| |------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 2.65 | | <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.51 |
## Modules ## Modules
...@@ -38,6 +36,7 @@ Note that this example may create resources which can cost money. Run `terraform ...@@ -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_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_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 ## Resources
...@@ -46,20 +45,22 @@ Note that this example may create resources which can cost money. Run `terraform ...@@ -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_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_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_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 ## Inputs
| Name | Description | Type | Default | Required | No inputs.
|------|-------------|------|---------|:--------:|
| <a name="input_instances_number"></a> [instances\_number](#input\_instances\_number) | NUmber of instances | `number` | `1` | no |
## Outputs ## Outputs
| Name | Description | | 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_ec2_arn"></a> [ec2\_arn](#output\_ec2\_arn) | The ARN of the instance |
| <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_ec2_capacity_reservation_specification"></a> [ec2\_capacity\_reservation\_specification](#output\_ec2\_capacity\_reservation\_specification) | Capacity reservation specification of the instance |
| <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_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 --> <!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
provider "aws" { provider "aws" {
region = "eu-west-1" region = local.region
} }
################################################################## locals {
# Data sources to get VPC, subnet, security group and AMI details availability_zone = "${local.region}a"
################################################################## name = "example-ec2-volume-attachment"
data "aws_vpc" "default" { region = "eu-west-1"
default = true tags = {
Owner = "user"
Environment = "dev"
}
} }
data "aws_subnet_ids" "all" { ################################################################################
vpc_id = data.aws_vpc.default.id # Supporting Resources
} ################################################################################
data "aws_ami" "amazon_linux" { module "vpc" {
most_recent = true source = "terraform-aws-modules/vpc/aws"
version = "~> 3.0"
owners = ["amazon"] name = local.name
cidr = "10.99.0.0/18"
filter { azs = ["${local.region}a", "${local.region}b", "${local.region}c"]
name = "name" 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 = [ tags = local.tags
"amzn-ami-hvm-*-x86_64-gp2", }
]
}
filter { data "aws_ami" "amazon_linux" {
name = "owner-alias" most_recent = true
owners = ["amazon"]
values = [ filter {
"amazon", name = "name"
] values = ["amzn-ami-hvm-*-x86_64-gp2"]
} }
} }
...@@ -39,39 +45,45 @@ module "security_group" { ...@@ -39,39 +45,45 @@ module "security_group" {
source = "terraform-aws-modules/security-group/aws" source = "terraform-aws-modules/security-group/aws"
version = "~> 4.0" version = "~> 4.0"
name = "example" name = local.name
description = "Security group for example usage with EC2 instance" 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_cidr_blocks = ["0.0.0.0/0"]
ingress_rules = ["http-80-tcp", "all-icmp"] ingress_rules = ["http-80-tcp", "all-icmp"]
egress_rules = ["all-all"] egress_rules = ["all-all"]
tags = local.tags
} }
################################################################################
# EC2 Module
################################################################################
module "ec2" { module "ec2" {
source = "../../" source = "../../"
instance_count = var.instances_number name = local.name
name = "example-with-ebs"
ami = data.aws_ami.amazon_linux.id ami = data.aws_ami.amazon_linux.id
instance_type = "c5.large" 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] vpc_security_group_ids = [module.security_group.security_group_id]
associate_public_ip_address = true associate_public_ip_address = true
tags = local.tags
} }
resource "aws_volume_attachment" "this" { resource "aws_volume_attachment" "this" {
count = var.instances_number
device_name = "/dev/sdh" device_name = "/dev/sdh"
volume_id = aws_ebs_volume.this[count.index].id volume_id = aws_ebs_volume.this.id
instance_id = module.ec2.id[count.index] instance_id = module.ec2.id
} }
resource "aws_ebs_volume" "this" { resource "aws_ebs_volume" "this" {
count = var.instances_number availability_zone = local.availability_zone
availability_zone = module.ec2.availability_zone[count.index]
size = 1 size = 1
tags = local.tags
} }
output "instances_public_ips" { # EC2
description = "Public IPs assigned to the EC2 instance" output "ec2_id" {
value = module.ec2.public_ip 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" { output "ec2_primary_network_interface_id" {
description = "The volume ID" description = "The ID of the instance's primary network interface"
value = aws_volume_attachment.this.*.volume_id value = module.ec2.primary_network_interface_id
} }
output "ebs_volume_attachment_instance_id" { output "ec2_private_dns" {
description = "The instance ID" 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 = aws_volume_attachment.this.*.instance_id 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 { terraform {
required_version = ">= 0.12.6" required_version = ">= 0.13.1"
required_providers { required_providers {
aws = ">= 2.65" aws = {
source = "hashicorp/aws"
version = ">= 3.51"
}
} }
} }
...@@ -3,29 +3,47 @@ locals { ...@@ -3,29 +3,47 @@ locals {
} }
resource "aws_instance" "this" { resource "aws_instance" "this" {
count = var.instance_count count = var.create ? 1 : 0
ami = var.ami ami = var.ami
instance_type = var.instance_type instance_type = var.instance_type
user_data = var.user_data cpu_core_count = var.cpu_core_count
user_data_base64 = var.user_data_base64 cpu_threads_per_core = var.cpu_threads_per_core
subnet_id = length(var.network_interface) > 0 ? null : element( user_data = var.user_data
distinct(compact(concat([var.subnet_id], var.subnet_ids))), user_data_base64 = var.user_data_base64
count.index, hibernation = var.hibernation
)
key_name = var.key_name availability_zone = var.availability_zone
monitoring = var.monitoring subnet_id = var.subnet_id
get_password_data = var.get_password_data
vpc_security_group_ids = var.vpc_security_group_ids 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 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_address_count = var.ipv6_address_count
ipv6_addresses = var.ipv6_addresses ipv6_addresses = var.ipv6_addresses
ebs_optimized = var.ebs_optimized 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" { dynamic "root_block_device" {
for_each = var.root_block_device for_each = var.root_block_device
content { content {
...@@ -65,7 +83,7 @@ resource "aws_instance" "this" { ...@@ -65,7 +83,7 @@ resource "aws_instance" "this" {
} }
dynamic "metadata_options" { dynamic "metadata_options" {
for_each = length(keys(var.metadata_options)) == 0 ? [] : [var.metadata_options] for_each = var.metadata_options != null ? [var.metadata_options] : []
content { content {
http_endpoint = lookup(metadata_options.value, "http_endpoint", "enabled") http_endpoint = lookup(metadata_options.value, "http_endpoint", "enabled")
http_tokens = lookup(metadata_options.value, "http_tokens", "optional") http_tokens = lookup(metadata_options.value, "http_tokens", "optional")
...@@ -82,29 +100,36 @@ resource "aws_instance" "this" { ...@@ -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 source_dest_check = length(var.network_interface) > 0 ? null : var.source_dest_check
disable_api_termination = var.disable_api_termination disable_api_termination = var.disable_api_termination
instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior instance_initiated_shutdown_behavior = var.instance_initiated_shutdown_behavior
placement_group = var.placement_group placement_group = var.placement_group
tenancy = var.tenancy tenancy = var.tenancy
cpu_core_count = var.cpu_core_count host_id = var.host_id
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
credit_specification { credit_specification {
cpu_credits = local.is_t_instance_type ? var.cpu_credits : null 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" { output "id" {
description = "List of IDs of instances" description = "The ID of the instance"
value = aws_instance.this.*.id value = element(concat(aws_instance.this.*.id, [""]), 0)
} }
output "arn" { output "arn" {
description = "List of ARNs of instances" description = "The ARN of the instance"
value = aws_instance.this.*.arn value = element(concat(aws_instance.this.*.arn, [""]), 0)
} }
output "availability_zone" { output "capacity_reservation_specification" {
description = "List of availability zones of instances" description = "Capacity reservation specification of the instance"
value = aws_instance.this.*.availability_zone value = element(concat(aws_instance.this.*.capacity_reservation_specification, [""]), 0)
} }
output "placement_group" { output "instance_state" {
description = "List of placement groups of instances" description = "The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped`"
value = aws_instance.this.*.placement_group value = element(concat(aws_instance.this.*.instance_state, [""]), 0)
} }
output "key_name" { output "outpost_arn" {
description = "List of key names of instances" description = "The ARN of the Outpost the instance is assigned to"
value = aws_instance.this.*.key_name value = element(concat(aws_instance.this.*.outpost_arn, [""]), 0)
} }
output "password_data" { output "password_data" {
description = "List of Base-64 encoded encrypted password data for the instance" 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 = aws_instance.this.*.password_data value = element(concat(aws_instance.this.*.password_data, [""]), 0)
}
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
} }
output "primary_network_interface_id" { output "primary_network_interface_id" {
description = "List of IDs of the primary network interface of instances" description = "The ID of the instance's primary network interface"
value = aws_instance.this.*.primary_network_interface_id value = element(concat(aws_instance.this.*.primary_network_interface_id, [""]), 0)
} }
output "private_dns" { 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" 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 = aws_instance.this.*.private_dns value = element(concat(aws_instance.this.*.private_dns, [""]), 0)
}
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
} }
output "subnet_id" { output "public_dns" {
description = "List of IDs of VPC subnets of instances" 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 = aws_instance.this.*.subnet_id value = element(concat(aws_instance.this.*.public_dns, [""]), 0)
}
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 "volume_tags" { output "public_ip" {
description = "List of tags of volumes of instances" 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 = aws_instance.this.*.volume_tags value = element(concat(aws_instance.this.*.public_ip, [""]), 0)
} }
output "instance_count" { output "tags_all" {
description = "Number of instances to launch specified as argument to this module" description = "A map of tags assigned to the resource, including those inherited from the provider default_tags configuration block"
value = var.instance_count value = element(concat(aws_instance.this.*.tags_all, [""]), 0)
} }
variable "name" { variable "create" {
description = "Name to be used on all resources as prefix" description = "Whether to create an instance"
type = string type = bool
default = true
} }
variable "instance_count" { variable "name" {
description = "Number of instances to launch" description = "Name to be used on EC2 instance created"
type = number type = string
default = 1 default = ""
} }
variable "ami" { variable "ami" {
description = "ID of AMI to use for the instance" description = "ID of AMI to use for the instance"
type = string type = string
}
variable "placement_group" {
description = "The Placement Group to start the instance in"
type = string
default = "" default = ""
} }
variable "get_password_data" { variable "associate_public_ip_address" {
description = "If true, wait for password data to become available and retrieve it." description = "Whether to associate a public IP address with an instance in a VPC"
type = bool type = bool
default = false default = null
} }
variable "tenancy" { variable "availability_zone" {
description = "The tenancy of the instance (if the instance is running in a VPC). Available values: default, dedicated, host." description = "AZ to start the instance in"
type = string type = string
default = "default" default = null
}
variable "ebs_optimized" {
description = "If true, the launched EC2 instance will be EBS-optimized"
type = bool
default = false
} }
variable "disable_api_termination" { variable "capacity_reservation_specification" {
description = "If true, enables EC2 Instance Termination Protection" description = "Describes an instance's Capacity Reservation targeting option"
type = bool type = any
default = false default = null
} }
variable "instance_initiated_shutdown_behavior" { variable "cpu_credits" {
description = "Shutdown behavior for the instance" # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingInstanceInitiatedShutdownBehavior description = "The credit option for CPU usage (unlimited or standard)"
type = string type = string
default = "" default = null
} }
variable "instance_type" { variable "disable_api_termination" {
description = "The type of instance to start" description = "If true, enables EC2 Instance Termination Protection"
type = string type = bool
default = null
} }
variable "key_name" { variable "ebs_block_device" {
description = "The key name to use for the instance" description = "Additional EBS block devices to attach to the instance"
type = string type = list(map(string))
default = "" default = []
} }
variable "monitoring" { variable "ebs_optimized" {
description = "If true, the launched EC2 instance will have detailed monitoring enabled" description = "If true, the launched EC2 instance will be EBS-optimized"
type = bool type = bool
default = false
}
variable "vpc_security_group_ids" {
description = "A list of security group IDs to associate with"
type = list(string)
default = null default = null
} }
variable "subnet_id" { variable "enclave_options_enabled" {
description = "The VPC Subnet ID to launch in" description = "Whether Nitro Enclaves will be enabled on the instance. Defaults to `false`"
type = string type = bool
default = "" default = null
} }
variable "subnet_ids" { variable "ephemeral_block_device" {
description = "A list of VPC Subnet IDs to launch in" description = "Customize Ephemeral (also known as Instance Store) volumes on the instance"
type = list(string) type = list(map(string))
default = [] default = []
} }
variable "associate_public_ip_address" { variable "get_password_data" {
description = "If true, the EC2 instance will have associated public IP address" description = "If true, wait for password data to become available and retrieve it."
type = bool type = bool
default = null default = null
} }
variable "private_ip" { variable "hibernation" {
description = "Private IP address to associate with the instance in a VPC" description = "If true, the launched EC2 instance will support hibernation"
type = string type = bool
default = null default = null
} }
variable "private_ips" { variable "host_id" {
description = "A list of private IP address to associate with the instance in a VPC. Should match the number of instances." description = "ID of a dedicated host that the instance will be assigned to. Use when an instance is to be launched on a specific dedicated host"
type = list(string) type = string
default = [] default = null
}
variable "source_dest_check" {
description = "Controls if traffic is routed to the instance when the destination address does not match the instance. Used for NAT or VPNs."
type = bool
default = true
} }
variable "user_data" { variable "iam_instance_profile" {
description = "The user data to provide when launching the instance. Do not pass gzip-compressed data via this argument; see user_data_base64 instead." description = "IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile"
type = string type = string
default = null default = null
} }
variable "user_data_base64" { variable "instance_initiated_shutdown_behavior" {
description = "Can be used instead of user_data to pass base64-encoded binary data directly. Use this instead of user_data whenever the value is not a valid UTF-8 string. For example, gzip-encoded user data must be base64-encoded and passed via this argument to avoid corruption." description = "Shutdown behavior for the instance. Amazon defaults this to stop for EBS-backed instances and terminate for instance-store instances. Cannot be set on instance-store instance" # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/terminating-instances.html#Using_ChangingInstanceInitiatedShutdownBehavior
type = string type = string
default = null default = null
} }
variable "iam_instance_profile" { variable "instance_type" {
description = "The IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile." description = "The type of instance to start"
type = string type = string
default = "" default = "t3.micro"
} }
variable "ipv6_address_count" { variable "ipv6_address_count" {
description = "A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet." description = "A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet"
type = number type = number
default = null default = null
} }
...@@ -139,22 +118,46 @@ variable "ipv6_addresses" { ...@@ -139,22 +118,46 @@ variable "ipv6_addresses" {
default = null default = null
} }
variable "tags" { variable "key_name" {
description = "A mapping of tags to assign to the resource" description = "Key name of the Key Pair to use for the instance; which can be managed using the `aws_key_pair` resource"
type = string
default = null
}
variable "launch_template" {
description = "Specifies a Launch Template to configure the instance. Parameters configured on this resource will override the corresponding parameters in the Launch Template"
type = map(string)
default = null
}
variable "metadata_options" {
description = "Customize the metadata options of the instance"
type = map(string) type = map(string)
default = {} default = {}
} }
variable "enable_volume_tags" { variable "monitoring" {
description = "Whether to enable volume tags (if enabled it conflicts with root_block_device tags)" description = "If true, the launched EC2 instance will have detailed monitoring enabled"
type = bool type = bool
default = true default = false
} }
variable "volume_tags" { variable "network_interface" {
description = "A mapping of tags to assign to the devices created by the instance at launch time" description = "Customize network interfaces to be attached at instance boot time"
type = map(string) type = list(map(string))
default = {} default = []
}
variable "placement_group" {
description = "The Placement Group to start the instance in"
type = string
default = null
}
variable "private_ip" {
description = "Private IP address to associate with the instance in a VPC"
type = string
default = null
} }
variable "root_block_device" { variable "root_block_device" {
...@@ -163,46 +166,70 @@ variable "root_block_device" { ...@@ -163,46 +166,70 @@ variable "root_block_device" {
default = [] default = []
} }
variable "ebs_block_device" { variable "secondary_private_ips" {
description = "Additional EBS block devices to attach to the instance" description = "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`"
type = list(map(string)) type = list(string)
default = [] default = null
} }
variable "ephemeral_block_device" { variable "source_dest_check" {
description = "Customize Ephemeral (also known as Instance Store) volumes on the instance" description = "Controls if traffic is routed to the instance when the destination address does not match the instance. Used for NAT or VPNs."
type = list(map(string)) type = bool
default = [] default = true
} }
variable "network_interface" { variable "subnet_id" {
description = "Customize network interfaces to be attached at instance boot time" description = "The VPC Subnet ID to launch in"
type = list(map(string)) type = string
default = [] default = null
} }
variable "cpu_credits" { variable "tags" {
description = "The credit option for CPU usage (unlimited or standard)" description = "A mapping of tags to assign to the resource"
type = map(string)
default = {}
}
variable "tenancy" {
description = "The tenancy of the instance (if the instance is running in a VPC). Available values: default, dedicated, host."
type = string type = string
default = "standard" default = null
} }
variable "metadata_options" { variable "user_data" {
description = "Customize the metadata options of the instance" description = "The user data to provide when launching the instance. Do not pass gzip-compressed data via this argument; see user_data_base64 instead."
type = string
default = null
}
variable "user_data_base64" {
description = "Can be used instead of user_data to pass base64-encoded binary data directly. Use this instead of user_data whenever the value is not a valid UTF-8 string. For example, gzip-encoded user data must be base64-encoded and passed via this argument to avoid corruption."
type = string
default = null
}
variable "volume_tags" {
description = "A mapping of tags to assign to the devices created by the instance at launch time"
type = map(string) type = map(string)
default = {} default = {}
} }
variable "use_num_suffix" { variable "enable_volume_tags" {
description = "Always append numerical suffix to instance name, even if instance_count is 1" description = "Whether to enable volume tags (if enabled it conflicts with root_block_device tags)"
type = bool type = bool
default = false default = true
} }
variable "num_suffix_format" { variable "vpc_security_group_ids" {
description = "Numerical suffix format used as the volume and EC2 instance name suffix" description = "A list of security group IDs to associate with"
type = string type = list(string)
default = "-%d" default = null
}
variable "timeouts" {
description = "Define maximum timeout for creating, updating, and deleting EC2 instance resources"
type = map(string)
default = {}
} }
variable "cpu_core_count" { variable "cpu_core_count" {
......
terraform { terraform {
required_version = ">= 0.12.6" required_version = ">= 0.13.1"
required_providers { 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