From 5fe43caf7494c296bfc110652718238d40e229ce Mon Sep 17 00:00:00 2001 From: Alisson Oliveira Date: Wed, 21 Feb 2024 08:36:50 +0000 Subject: [PATCH] fix: Setting var.launch_template doesn't work due to default ami and instance_type vars --- examples/launch-template/README.md | 78 ++++++++++++++++++ examples/launch-template/main.tf | 109 ++++++++++++++++++++++++++ examples/launch-template/outputs.tf | 94 ++++++++++++++++++++++ examples/launch-template/variables.tf | 0 examples/launch-template/versions.tf | 14 ++++ main.tf | 12 +-- 6 files changed, 301 insertions(+), 6 deletions(-) create mode 100644 examples/launch-template/README.md create mode 100644 examples/launch-template/main.tf create mode 100644 examples/launch-template/outputs.tf create mode 100644 examples/launch-template/variables.tf create mode 100644 examples/launch-template/versions.tf diff --git a/examples/launch-template/README.md b/examples/launch-template/README.md new file mode 100644 index 00000000..1f43882d --- /dev/null +++ b/examples/launch-template/README.md @@ -0,0 +1,78 @@ +# EC2 instance with Launch template + +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. + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0 | +| [aws](#requirement\_aws) | >= 4.66 | +| [tls](#requirement\_tls) | >= 4.0.5 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 4.66 | +| [tls](#provider\_tls) | >= 4.0.5 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [ec2\_from\_launch\_template](#module\_ec2\_from\_launch\_template) | ../../ | n/a | +| [security\_group](#module\_security\_group) | terraform-aws-modules/security-group/aws | ~> 4.0 | +| [vpc](#module\_vpc) | terraform-aws-modules/vpc/aws | ~> 5.0 | + +## Resources + +| Name | Type | +|------|------| +| [aws_key_pair.tf_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/key_pair) | resource | +| [aws_launch_template.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template) | resource | +| [tls_private_key.ed25519](https://registry.terraform.io/providers/hashicorp/tls/latest/docs/resources/private_key) | resource | +| [aws_ami.amazon_linux_23](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ami) | data source | +| [aws_availability_zones.available](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/availability_zones) | data source | + +## Inputs + +No inputs. + +## Outputs + +| Name | Description | +|------|-------------| +| [ec2\_arn](#output\_ec2\_arn) | The ARN of the instance | +| [ec2\_availability\_zone](#output\_ec2\_availability\_zone) | The availability zone of the created instance | +| [ec2\_capacity\_reservation\_specification](#output\_ec2\_capacity\_reservation\_specification) | Capacity reservation specification of the instance | +| [ec2\_ebs\_block\_device](#output\_ec2\_ebs\_block\_device) | EBS block device information | +| [ec2\_ephemeral\_block\_device](#output\_ec2\_ephemeral\_block\_device) | Ephemeral block device information | +| [ec2\_iam\_instance\_profile\_arn](#output\_ec2\_iam\_instance\_profile\_arn) | ARN assigned by AWS to the instance profile | +| [ec2\_iam\_instance\_profile\_id](#output\_ec2\_iam\_instance\_profile\_id) | Instance profile's ID | +| [ec2\_iam\_instance\_profile\_unique](#output\_ec2\_iam\_instance\_profile\_unique) | Stable and unique string identifying the IAM instance profile | +| [ec2\_iam\_role\_arn](#output\_ec2\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role | +| [ec2\_iam\_role\_name](#output\_ec2\_iam\_role\_name) | The name of the IAM role | +| [ec2\_iam\_role\_unique\_id](#output\_ec2\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role | +| [ec2\_id](#output\_ec2\_id) | The ID of the instance | +| [ec2\_instance\_state](#output\_ec2\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` | +| [ec2\_primary\_network\_interface\_id](#output\_ec2\_primary\_network\_interface\_id) | The ID of the instance's primary network interface | +| [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 | +| [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 | +| [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 | +| [ec2\_root\_block\_device](#output\_ec2\_root\_block\_device) | Root block device information | +| [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 | + diff --git a/examples/launch-template/main.tf b/examples/launch-template/main.tf new file mode 100644 index 00000000..cd90cf3c --- /dev/null +++ b/examples/launch-template/main.tf @@ -0,0 +1,109 @@ +provider "aws" { + region = local.region +} + +data "aws_availability_zones" "available" {} + +locals { + name = "ex-${basename(path.cwd)}" + region = "eu-west-1" + + vpc_cidr = "10.0.0.0/16" + azs = slice(data.aws_availability_zones.available.names, 0, 3) + + user_data = <<-EOT + #!/bin/bash + echo "Hello Terraform!" + EOT + + tags = { + Name = local.name + Example = local.name + Repository = "https://github.com/terraform-aws-modules/terraform-aws-ec2-instance" + } +} + +################################################################################ +# EC2 Module +################################################################################ + +module "ec2_from_launch_template" { + source = "../../" + + name = local.name + + launch_template = { + id = aws_launch_template.this.id + } + + tags = local.tags +} + +################################################################################ +# Supporting Resources +################################################################################ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 5.0" + + name = local.name + cidr = local.vpc_cidr + + azs = local.azs + private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)] + public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)] + + tags = local.tags +} + +data "aws_ami" "amazon_linux_23" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["al2023-ami-2023*-x86_64"] + } +} + +module "security_group" { + source = "terraform-aws-modules/security-group/aws" + version = "~> 4.0" + + name = local.name + description = "Security group for example usage with EC2 instance" + vpc_id = module.vpc.vpc_id + + ingress_cidr_blocks = ["0.0.0.0/0"] + ingress_rules = ["http-80-tcp", "all-icmp"] + egress_rules = ["all-all"] + + tags = local.tags +} + +resource "tls_private_key" "ed25519" { + algorithm = "ED25519" +} + +resource "aws_key_pair" "tf_key" { + key_name = "terraform-ec2-instances-example" + public_key = tls_private_key.ed25519.public_key_openssh +} + +resource "aws_launch_template" "this" { + image_id = data.aws_ami.amazon_linux_23.id + instance_type = "c5.large" + key_name = aws_key_pair.tf_key.key_name + user_data = local.user_data + + network_interfaces { + security_groups = [module.security_group.security_group_id] + subnet_id = module.vpc.private_subnets[0] + } + + tag_specifications { + resource_type = "instance" + tags = local.tags + } +} diff --git a/examples/launch-template/outputs.tf b/examples/launch-template/outputs.tf new file mode 100644 index 00000000..79628ee6 --- /dev/null +++ b/examples/launch-template/outputs.tf @@ -0,0 +1,94 @@ +output "ec2_id" { + description = "The ID of the instance" + value = module.ec2_from_launch_template.id +} + +output "ec2_arn" { + description = "The ARN of the instance" + value = module.ec2_from_launch_template.arn +} + +output "ec2_capacity_reservation_specification" { + description = "Capacity reservation specification of the instance" + value = module.ec2_from_launch_template.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_from_launch_template.instance_state +} + +output "ec2_primary_network_interface_id" { + description = "The ID of the instance's primary network interface" + value = module.ec2_from_launch_template.primary_network_interface_id +} + +output "ec2_private_dns" { + description = "The private DNS name assigned to the instance. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC" + value = module.ec2_from_launch_template.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_from_launch_template.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_from_launch_template.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_from_launch_template.tags_all +} + +output "ec2_iam_role_name" { + description = "The name of the IAM role" + value = module.ec2_from_launch_template.iam_role_name +} + +output "ec2_iam_role_arn" { + description = "The Amazon Resource Name (ARN) specifying the IAM role" + value = module.ec2_from_launch_template.iam_role_arn +} + +output "ec2_iam_role_unique_id" { + description = "Stable and unique string identifying the IAM role" + value = module.ec2_from_launch_template.iam_role_unique_id +} + +output "ec2_iam_instance_profile_arn" { + description = "ARN assigned by AWS to the instance profile" + value = module.ec2_from_launch_template.iam_instance_profile_arn +} + +output "ec2_iam_instance_profile_id" { + description = "Instance profile's ID" + value = module.ec2_from_launch_template.iam_instance_profile_id +} + +output "ec2_iam_instance_profile_unique" { + description = "Stable and unique string identifying the IAM instance profile" + value = module.ec2_from_launch_template.iam_instance_profile_unique +} + +output "ec2_root_block_device" { + description = "Root block device information" + value = module.ec2_from_launch_template.root_block_device +} + +output "ec2_ebs_block_device" { + description = "EBS block device information" + value = module.ec2_from_launch_template.ebs_block_device +} + +output "ec2_ephemeral_block_device" { + description = "Ephemeral block device information" + value = module.ec2_from_launch_template.ephemeral_block_device +} + +output "ec2_availability_zone" { + description = "The availability zone of the created instance" + value = module.ec2_from_launch_template.availability_zone +} diff --git a/examples/launch-template/variables.tf b/examples/launch-template/variables.tf new file mode 100644 index 00000000..e69de29b diff --git a/examples/launch-template/versions.tf b/examples/launch-template/versions.tf new file mode 100644 index 00000000..fd247cc9 --- /dev/null +++ b/examples/launch-template/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 1.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 4.66" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.5" + } + } +} diff --git a/main.tf b/main.tf index 2f291307..000eabdb 100644 --- a/main.tf +++ b/main.tf @@ -21,8 +21,8 @@ data "aws_ssm_parameter" "this" { resource "aws_instance" "this" { count = local.create && !var.ignore_ami_changes && !var.create_spot_instance ? 1 : 0 - ami = local.ami - instance_type = var.instance_type + ami = length(var.launch_template) == 0 ? local.ami : null + instance_type = length(var.launch_template) == 0 ? var.instance_type : null cpu_core_count = var.cpu_core_count cpu_threads_per_core = var.cpu_threads_per_core hibernation = var.hibernation @@ -199,8 +199,8 @@ resource "aws_instance" "this" { resource "aws_instance" "ignore_ami" { count = local.create && var.ignore_ami_changes && !var.create_spot_instance ? 1 : 0 - ami = local.ami - instance_type = var.instance_type + ami = length(var.launch_template) == 0 ? local.ami : null + instance_type = length(var.launch_template) == 0 ? var.instance_type : null cpu_core_count = var.cpu_core_count cpu_threads_per_core = var.cpu_threads_per_core hibernation = var.hibernation @@ -383,8 +383,8 @@ resource "aws_instance" "ignore_ami" { resource "aws_spot_instance_request" "this" { count = local.create && var.create_spot_instance ? 1 : 0 - ami = local.ami - instance_type = var.instance_type + ami = length(var.launch_template) == 0 ? local.ami : null + instance_type = length(var.launch_template) == 0 ? var.instance_type : null cpu_core_count = var.cpu_core_count cpu_threads_per_core = var.cpu_threads_per_core hibernation = var.hibernation