159 lines
6.8 KiB
HCL
159 lines
6.8 KiB
HCL
locals {
|
|
use = var.use # the strategy to use for selecting or creating a server
|
|
image = var.image # the image object from the image module to use for the ec2 instance
|
|
select = (local.use == "select" ? 1 : 0)
|
|
create = (local.use == "create" ? 1 : 0)
|
|
id = var.id # the id of a server to select
|
|
name = var.name # the name to give the new server
|
|
type = var.type # the designation from types.tf
|
|
# tflint-ignore: terraform_unused_declarations
|
|
fail_type = (local.create == 1 && local.server_type == null ? one([local.type, "type_not_found"]) : false)
|
|
ip_family = var.ip_family
|
|
server_type = lookup(local.types, local.type, null)
|
|
security_group = var.security_group # the name of the security group to find and assign to the server
|
|
subnet = var.subnet # the name of the subnet to find and assign to the server
|
|
cloudinit = var.cloudinit # the cloudinit content to associate with the server
|
|
|
|
aws_keypair_use_strategy = var.aws_keypair_use_strategy
|
|
ssh_key = var.ssh_key
|
|
ssh_key_name = var.ssh_key_name
|
|
|
|
ip = var.ip # ip to assign to the server
|
|
ipv4 = ((local.ip_family == "ipv4" || local.ip_family == "dualstack") ? local.ip : "")
|
|
ipv6 = (local.ip_family == "ipv6" ? local.ip : "")
|
|
}
|
|
|
|
# select
|
|
# WARNING! When selecting a server nothing else will be done
|
|
data "aws_instance" "selected" {
|
|
count = local.select
|
|
instance_id = local.id
|
|
}
|
|
data "aws_ec2_instance_type" "general_info_select" {
|
|
count = local.select
|
|
instance_type = data.aws_instance.selected[0].instance_type
|
|
}
|
|
data "aws_subnet" "general_info_select" {
|
|
count = local.select
|
|
id = data.aws_instance.selected[0].subnet_id
|
|
}
|
|
data "aws_vpc" "general_info_select" {
|
|
count = local.select
|
|
id = data.aws_subnet.general_info_select[0].vpc_id
|
|
}
|
|
data "aws_ec2_instance_type" "general_info_create" {
|
|
count = local.create
|
|
instance_type = local.server_type.id
|
|
}
|
|
data "aws_security_group" "general_info_create" {
|
|
count = local.create
|
|
filter {
|
|
name = "tag:Name"
|
|
values = [local.security_group]
|
|
}
|
|
}
|
|
data "aws_subnet" "general_info_create" {
|
|
count = local.create
|
|
filter {
|
|
name = "tag:Name"
|
|
values = [local.subnet]
|
|
}
|
|
}
|
|
data "aws_availability_zone" "general_info_create" {
|
|
count = local.create
|
|
name = data.aws_subnet.general_info_create[0].availability_zone
|
|
}
|
|
data "aws_vpc" "general_info_create" {
|
|
count = local.create
|
|
id = data.aws_security_group.general_info_create[0].vpc_id
|
|
}
|
|
data "aws_key_pair" "ssh_key_selected" {
|
|
count = (local.aws_keypair_use_strategy == "select" ? 1 : 0)
|
|
key_name = local.ssh_key_name
|
|
}
|
|
resource "aws_key_pair" "created" {
|
|
count = (local.aws_keypair_use_strategy == "create" ? local.create : 0)
|
|
key_name = local.ssh_key_name
|
|
public_key = local.ssh_key
|
|
}
|
|
resource "aws_instance" "created" {
|
|
count = local.create
|
|
depends_on = [
|
|
data.aws_security_group.general_info_create,
|
|
data.aws_subnet.general_info_create,
|
|
aws_key_pair.created,
|
|
]
|
|
ami = local.image.id
|
|
instance_type = data.aws_ec2_instance_type.general_info_create[0].id
|
|
key_name = (local.aws_keypair_use_strategy != "skip" ? (local.aws_keypair_use_strategy == "create" ? aws_key_pair.created[0].key_name : data.aws_key_pair.ssh_key_selected[0].key_name) : "")
|
|
|
|
subnet_id = data.aws_subnet.general_info_create[0].id
|
|
private_ip = (local.ipv4 != "" ? local.ipv4 : null)
|
|
ipv6_addresses = (local.ipv6 != "" ? [local.ipv6] : null)
|
|
|
|
instance_initiated_shutdown_behavior = "stop" # termination can be handled by destroy or separately
|
|
user_data_base64 = local.cloudinit
|
|
user_data_replace_on_change = true # rebuild the server if the user data changes
|
|
availability_zone = data.aws_subnet.general_info_create[0].availability_zone
|
|
security_groups = [data.aws_security_group.general_info_create[0].id]
|
|
tags = {
|
|
Name = local.name
|
|
}
|
|
|
|
root_block_device {
|
|
delete_on_termination = true
|
|
volume_size = local.server_type.storage
|
|
tags = {
|
|
Name = local.name
|
|
}
|
|
}
|
|
lifecycle {
|
|
# so what does cause the server to rebuild?
|
|
# - directly changing: name, instance type, or storage type
|
|
ignore_changes = [
|
|
tags, # amazon updates tags automatically, ignore this change
|
|
tags_all, # amazon updates tags automatically, ignore this change
|
|
root_block_device[0].tags_all, # amazon updates tags automatically, ignore this change
|
|
availability_zone, # this is dependant on the aws subnet lookup and if not ignored will cause the server to always rebuild
|
|
network_interface, # this is dependant on the aws subnet lookup and if not ignored will cause the server to always rebuild
|
|
ami, # this is dependant on the aws ami lookup and if not ignored will cause the server to always rebuild
|
|
subnet_id, # this is dependant on the aws subnet lookup and if not ignored will cause the server to always rebuild
|
|
private_ip, # this is dependant on the aws subnet lookup and if not ignored will cause the server to always rebuild
|
|
ipv6_addresses, # this is dependant on the aws subnet lookup and if not ignored will cause the server to always rebuild
|
|
security_groups, # this is dependant on the aws security group lookup and if not ignored will cause the server to always rebuild
|
|
]
|
|
}
|
|
}
|
|
|
|
# WARNING! This forces a dependency on the AWS CLI, but only for "ipv6 only" servers.
|
|
# This is a workaround for the fact that the terraform AWS provider doesn't support the primary ipv6 flag yet.
|
|
# When the provider supports it, this can be removed and the attribute added to the instance resource.
|
|
resource "terraform_data" "set_primary_ipv6" {
|
|
count = (local.ip_family == "ipv6" ? local.create : 0)
|
|
depends_on = [
|
|
data.aws_security_group.general_info_create,
|
|
data.aws_subnet.general_info_create,
|
|
aws_key_pair.created,
|
|
aws_instance.created,
|
|
]
|
|
triggers_replace = {
|
|
"aws_instance" = aws_instance.created[0].id
|
|
}
|
|
provisioner "local-exec" {
|
|
command = <<-EOT
|
|
if ! aws ec2 describe-network-interfaces \
|
|
--network-interface-ids ${aws_instance.created[0].primary_network_interface_id} \
|
|
--region ${data.aws_availability_zone.general_info_create[0].region} \
|
|
--query 'NetworkInterfaces[0].Ipv6Addresses[?IsPrimaryIpv6==`true`]' \
|
|
--output text | grep -q .; then
|
|
aws ec2 modify-network-interface-attribute \
|
|
--network-interface-id ${aws_instance.created[0].primary_network_interface_id} \
|
|
--enable-primary-ipv6 \
|
|
--region ${data.aws_availability_zone.general_info_create[0].region}
|
|
else
|
|
echo "Primary IPv6 is already enabled for this network interface"
|
|
fi
|
|
EOT
|
|
}
|
|
}
|