Skip to content

Terraform module to provisioning new AWS Launch Template

License

Notifications You must be signed in to change notification settings

Infrastrukturait/terraform-aws-launch-template

Repository files navigation

terraform-aws-launch-template

WeSupportUkraine

About

Terraform module to provision new Launch Template on AWS.

License

License: MIT

The MIT License (MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Source: <https://opensource.org/licenses/MIT>

See LICENSE for full details.

Authors

Documentation

Requirements

Name Version
terraform >= 0.14
aws >= 2.0.0

Modules

No modules.

Resources

Name Type
aws_launch_template.this resource

Inputs

Name Description Type Default Required
block_device_mappings Specify volumes to attach to the instance besides the volumes specified by the AMI. list(any) [] no
capacity_reservation_specification Targeting for EC2 capacity reservations. any {} no
cpu_options The CPU options for the instance. map(string) {} no
credit_specification Customize the credit specification of the instance. map(string) {} no
default_version Default Version of the launch template. string null no
description Description of the launch template. string null no
disable_api_stop If true, enables EC2 instance stop protection. bool null no
disable_api_termination If true, enables EC2 instance termination protection. bool null no
ebs_optimized If true, the launched EC2 instance will be EBS-optimized. bool null no
elastic_gpu_specifications The elastic GPU to attach to the instance. map(string) {} no
elastic_inference_accelerator Configuration block containing an Elastic Inference Accelerator to attach to the instance. map(string) {} no
enable_monitoring Enables/disables detailed monitoring. bool true no
enclave_options Enable Nitro Enclaves on launched instances. map(string) {} no
hibernation_options The hibernation options for the instance. map(string) {} no
iam_instance_profile_arn Amazon Resource Name (ARN) of an existing IAM instance profile. string null no
iam_instance_profile_name The name of the IAM instance profile. string null no
image_id The AMI from which to launch the instance. string "" no
instance_initiated_shutdown_behavior Shutdown behavior for the instance.
Can be stop or terminate. (Default: stop)
string "stop" no
instance_market_options The market (purchasing) option for the instance. any {} no
instance_requirements The attribute requirements for the type of instance.
If present then instance_type cannot be present.
any {} no
instance_type The type of the instance. If present then instance_requirements cannot be present. string null no
kernel_id The kernel ID. string null no
key_name The key name that should be used for the instance. string null no
license_specifications A list of license specifications to associate with. map(string) {} no
maintenance_options The maintenance options for the instance. any {} no
metadata_options Customize the metadata options for the instance. map(string) {} no
name Name of launch template to be created. string "" no
network_interfaces Customize network interfaces to be attached at instance boot time. list(any) [] no
placement The placement of the instance. map(string) {} no
private_dns_name_options The options for the instance hostname. The default values are inherited from the subnet. map(string) {} no
ram_disk_id The ID of the ram disk. string null no
security_groups A list of security group IDs to associate. list(string) [] no
tag_specifications The tags to apply to the resources during launch. list(any) [] no
tags A map of tags to assign to resources. map(string) {} no
update_default_version Whether to update Default Version each update.
Conflicts with default_version.
string null no
use_name_prefix Determines whether to use launch_template_name
as is or create a unique name beginning with the launch_template_name as the prefix.
bool true no
user_data The Base64-encoded user data to provide when launching the instance. string null no

Outputs

Name Description
launch_template_arn The ARN of the launch template
launch_template_default_version The default version of the launch template
launch_template_id The ID of the launch template
launch_template_latest_version The latest version of the launch template
launch_template_name The name of the launch template

Examples

locals {
  user_data = <<-EOT
    #!/bin/bash
    yum update -y
    yum install -y httpd
    systemctl enable --now httpd.service
    echo "Hello World from $(hostname -f)" > /var/www/html/index.html
  EOT
}

module "app_prod_web_label" {
  source  = "cloudposse/label/null"
  version = "v0.25.0"

  namespace  = "app"
  stage      = "prod"
  name       = "web"
  attributes = ["private"]
  delimiter  = "-"

  tags = {
    "BusinessUnit" = "XYZ",
  }
}

data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["137112412989"]

  filter {
    name = "name"

    values = [
      "amzn2-ami-hvm-*-x86_64-gp2",
    ]
  }
}

resource "aws_iam_role" "ssm" {
  name = join(module.app_prod_web_label.delimiter, [module.app_prod_web_label.stage, module.app_prod_web_label.name, "role"])

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "sts:AssumeRole",
        Principal = {
          Service = "ec2.amazonaws.com"
        },
        Effect = "Allow",
        Sid    = ""
      }
    ]
  })

  tags = module.app_prod_web_label.tags
}

resource "aws_iam_instance_profile" "ssm" {
  name = join(module.app_prod_web_label.delimiter, [module.app_prod_web_label.stage, module.app_prod_web_label.name, "instance", "profile"])
  role = aws_iam_role.ssm.name

  tags = module.app_prod_web_label.tags
}

module "http_sg" {
  source  = "terraform-aws-modules/security-group/aws//modules/http-80"
  version = "~> 4.0"

  vpc_id = var.vpc_id

  name        = join(module.app_prod_web_label.delimiter, [module.app_prod_web_label.stage, module.app_prod_web_label.name, "sg"])
  description = "Security group for open HTTP protocol"

  ingress_cidr_blocks = ["0.0.0.0/0"]

  tags = module.app_prod_web_label.tags
}

module "app_prod_web" {
  source      = "../../"
  name        = join(module.app_prod_web_label.delimiter, [module.app_prod_web_label.stage, module.app_prod_web_label.name, "web-server"])
  description = "This is launch template to provisioning web servers"

  image_id      = data.aws_ami.amazon_linux.id
  instance_type = "t3.micro"

  user_data = base64encode(local.user_data)

  ebs_optimized     = true
  enable_monitoring = true

  update_default_version   = true
  iam_instance_profile_arn = aws_iam_instance_profile.ssm.arn

  security_groups = [module.http_sg.security_group_id]

  key_name = var.key_name

  block_device_mappings = [
    {
      # Root volume
      device_name = "/dev/xvda"
      no_device   = 0
      ebs = {
        delete_on_termination = true
        encrypted             = true
        volume_size           = 20
        volume_type           = "gp2"
      }
    },
    {
      device_name = "/dev/sda1"
      no_device   = 1
      ebs = {
        delete_on_termination = true
        encrypted             = true
        volume_size           = 30
        volume_type           = "gp2"
      }
    }
  ]

  metadata_options = {
    http_endpoint               = "enabled"
    http_tokens                 = "required"
    http_put_response_hop_limit = 32
    instance_metadata_tags      = "enabled"
  }

  tag_specifications = [
    {
      resource_type = "instance"
      tags          = { WhatAmI = "Instance" }
    },
    {
      resource_type = "volume"
      tags          = merge({ WhatAmI = "Volume" })
    }
  ]

  tags = module.app_prod_web_label.tags
}