From bffa44411158c1d0b2776ad5d8ad51fc92a8d105 Mon Sep 17 00:00:00 2001 From: Anton Babenko Date: Fri, 8 Jun 2018 19:45:18 +0200 Subject: [PATCH] Fixed t2-unlimited bug (related issue #35) --- examples/basic/README.md | 10 ++++++--- examples/basic/main.tf | 18 ++++++++++++++- examples/basic/outputs.tf | 30 ++++++++++++++++++++----- main.tf | 47 ++++++++++++++++++++++++++++++++++++--- outputs.tf | 45 +++++++++++++++++++++++++------------ 5 files changed, 124 insertions(+), 26 deletions(-) diff --git a/examples/basic/README.md b/examples/basic/README.md index 85e74d54..307e64e0 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -1,6 +1,6 @@ # Basic EC2 instance -Configuration in this directory creates single EC2 instance with minimum set of arguments: AMI ID and instance type. It will also assign Elastic IP (EIP) to an instance. +Configuration in this directory creates EC2 instances with minimum set of arguments. It will also assign Elastic IP (EIP) to an instance. Unspecified arguments for security group id and subnet are inherited from the default VPC. @@ -24,10 +24,14 @@ Note that this example may create resources which can cost money. Run `terraform | Name | Description | |------|-------------| -| credit_specification | Credit specification of EC2 instance | -| id | List of IDs of instances | +| credit_specification | Credit specification of EC2 instance (empty list for not t2 instance types) | +| credit_specification_t2_unlimited | Credit specification of t2-type EC2 instance | +| ids | List of IDs of instances | +| ids_t2 | List of IDs of t2-type instances | | instance_id | EC2 instance ID | | instance_public_dns | Public DNS name assigned to the EC2 instance | | public_dns | List of public DNS names assigned to the instances | +| tags | List of tags | +| vpc_security_group_ids | List of VPC security group ids assigned to the instances | diff --git a/examples/basic/main.tf b/examples/basic/main.tf index 409e9164..c9e0c9e9 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -53,9 +53,25 @@ resource "aws_eip" "this" { module "ec2" { source = "../../" - name = "example" + instance_count = 2 + + name = "example-normal" + ami = "${data.aws_ami.amazon_linux.id}" + instance_type = "m4.large" + subnet_id = "${element(data.aws_subnet_ids.all.ids, 0)}" + vpc_security_group_ids = ["${module.security_group.this_security_group_id}"] + associate_public_ip_address = true +} + +module "ec2_with_t2_unlimited" { + source = "../../" + + instance_count = 2 + + name = "example-t2-unlimited" ami = "${data.aws_ami.amazon_linux.id}" instance_type = "t2.micro" + cpu_credits = "unlimited" subnet_id = "${element(data.aws_subnet_ids.all.ids, 0)}" vpc_security_group_ids = ["${module.security_group.this_security_group_id}"] associate_public_ip_address = true diff --git a/examples/basic/outputs.tf b/examples/basic/outputs.tf index 138e9af0..8b3bec9d 100644 --- a/examples/basic/outputs.tf +++ b/examples/basic/outputs.tf @@ -1,11 +1,26 @@ -output "id" { +output "ids" { description = "List of IDs of instances" - value = ["${module.ec2.id}"] + 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}"] + 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 "tags" { + description = "List of tags" + value = "${module.ec2.tags}" } output "instance_id" { @@ -19,6 +34,11 @@ output "instance_public_dns" { } output "credit_specification" { - description = "Credit specification of EC2 instance" - value = "${module.ec2.credit_specification[0]}" + 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}" } diff --git a/main.tf b/main.tf index 646524b4..d2040c1a 100644 --- a/main.tf +++ b/main.tf @@ -1,10 +1,51 @@ +locals { + is_t2_instance_type = "${replace(replace(var.instance_type, "/^[^t2].*/", "0"), "/^t2.*$/", "1")}" +} + ###### -# EC2 instance -# # Note: network_interface can't be specified together with associate_public_ip_address ###### resource "aws_instance" "this" { - count = "${var.instance_count}" + count = "${var.instance_count * (1 - local.is_t2_instance_type)}" + + ami = "${var.ami}" + instance_type = "${var.instance_type}" + user_data = "${var.user_data}" + subnet_id = "${var.subnet_id}" + key_name = "${var.key_name}" + monitoring = "${var.monitoring}" + vpc_security_group_ids = ["${var.vpc_security_group_ids}"] + iam_instance_profile = "${var.iam_instance_profile}" + + associate_public_ip_address = "${var.associate_public_ip_address}" + private_ip = "${var.private_ip}" + ipv6_address_count = "${var.ipv6_address_count}" + ipv6_addresses = "${var.ipv6_addresses}" + + ebs_optimized = "${var.ebs_optimized}" + volume_tags = "${var.volume_tags}" + root_block_device = "${var.root_block_device}" + ebs_block_device = "${var.ebs_block_device}" + ephemeral_block_device = "${var.ephemeral_block_device}" + + source_dest_check = "${var.source_dest_check}" + disable_api_termination = "${var.disable_api_termination}" + instance_initiated_shutdown_behavior = "${var.instance_initiated_shutdown_behavior}" + placement_group = "${var.placement_group}" + tenancy = "${var.tenancy}" + + tags = "${merge(var.tags, map("Name", var.instance_count > 1 ? format("%s-%d", var.name, count.index+1) : var.name))}" + + lifecycle { + # Due to several known issues in Terraform AWS provider related to arguments of aws_instance: + # (eg, https://github.com/terraform-providers/terraform-provider-aws/issues/2036) + # we have to ignore changes in the following arguments + ignore_changes = ["private_ip", "root_block_device"] + } +} + +resource "aws_instance" "this_t2" { + count = "${var.instance_count * local.is_t2_instance_type}" ami = "${var.ami}" instance_type = "${var.instance_type}" diff --git a/outputs.tf b/outputs.tf index 6907e349..0c038d4d 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,11 +1,28 @@ +locals { + this_id = "${compact(concat(coalescelist(aws_instance.this.*.id, aws_instance.this_t2.*.id), list("")))}" + this_availability_zone = "${compact(concat(coalescelist(aws_instance.this.*.availability_zone, aws_instance.this_t2.*.availability_zone), list("")))}" + this_key_name = "${compact(concat(coalescelist(aws_instance.this.*.key_name, aws_instance.this_t2.*.key_name), list("")))}" + this_public_dns = "${compact(concat(coalescelist(aws_instance.this.*.public_dns, aws_instance.this_t2.*.public_dns), list("")))}" + this_public_ip = "${compact(concat(coalescelist(aws_instance.this.*.public_ip, aws_instance.this_t2.*.public_ip), list("")))}" + this_network_interface_id = "${compact(concat(coalescelist(aws_instance.this.*.network_interface_id, aws_instance.this_t2.*.network_interface_id), list("")))}" + this_primary_network_interface_id = "${compact(concat(coalescelist(aws_instance.this.*.primary_network_interface_id, aws_instance.this_t2.*.primary_network_interface_id), list("")))}" + this_private_dns = "${compact(concat(coalescelist(aws_instance.this.*.private_dns, aws_instance.this_t2.*.private_dns), list("")))}" + this_private_ip = "${compact(concat(coalescelist(aws_instance.this.*.private_ip, aws_instance.this_t2.*.private_ip), list("")))}" + this_security_groups = "${compact(concat(coalescelist(flatten(aws_instance.this.*.security_groups), flatten(aws_instance.this_t2.*.security_groups)), list("")))}" + this_vpc_security_group_ids = "${compact(concat(coalescelist(flatten(aws_instance.this.*.vpc_security_group_ids), flatten(aws_instance.this_t2.*.vpc_security_group_ids)), list("")))}" + this_subnet_id = "${compact(concat(coalescelist(aws_instance.this.*.subnet_id, aws_instance.this_t2.*.subnet_id), list("")))}" + this_credit_specification = "${aws_instance.this_t2.*.credit_specification}" + this_tags = "${coalescelist(flatten(aws_instance.this.*.tags), flatten(aws_instance.this_t2.*.tags))}" +} + output "id" { description = "List of IDs of instances" - value = ["${aws_instance.this.*.id}"] + value = ["${local.this_id}"] } output "availability_zone" { description = "List of availability zones of instances" - value = ["${aws_instance.this.*.availability_zone}"] + value = ["${local.this_availability_zone}"] } // GH issue: https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/issues/8 @@ -16,60 +33,60 @@ output "availability_zone" { output "key_name" { description = "List of key names of instances" - value = ["${aws_instance.this.*.key_name}"] + value = ["${local.this_key_name}"] } 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}"] + value = ["${local.this_public_dns}"] } output "public_ip" { description = "List of public IP addresses assigned to the instances, if applicable" - value = ["${aws_instance.this.*.public_ip}"] + value = ["${local.this_public_ip}"] } output "network_interface_id" { description = "List of IDs of the network interface of instances" - value = ["${aws_instance.this.*.network_interface_id}"] + value = ["${local.this_network_interface_id}"] } output "primary_network_interface_id" { description = "List of IDs of the primary network interface of instances" - value = ["${aws_instance.this.*.primary_network_interface_id}"] + value = ["${local.this_primary_network_interface_id}"] } output "private_dns" { description = "List of private DNS names assigned to the instances. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC" - value = ["${aws_instance.this.*.private_dns}"] + value = ["${local.this_private_dns}"] } output "private_ip" { description = "List of private IP addresses assigned to the instances" - value = ["${aws_instance.this.*.private_ip}"] + value = ["${local.this_private_ip}"] } output "security_groups" { description = "List of associated security groups of instances" - value = ["${aws_instance.this.*.security_groups}"] + value = ["${local.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}"] + value = ["${local.this_vpc_security_group_ids}"] } output "subnet_id" { description = "List of IDs of VPC subnets of instances" - value = ["${aws_instance.this.*.subnet_id}"] + value = ["${local.this_subnet_id}"] } output "credit_specification" { description = "List of credit specification of instances" - value = ["${aws_instance.this.*.credit_specification}"] + value = ["${local.this_credit_specification}"] } output "tags" { description = "List of tags of instances" - value = ["${aws_instance.this.*.tags}"] + value = ["${local.this_tags}"] }