Elastic IP for autoscaling group terraform - amazon-web-services

What's the best approach for use a same ip on autoscaling group without use a load balancer?
I need to use a route53 subdomain to route to instance on autoscaling group.
For now i try to associate a elastic ip to network interface
I have this:
resource "aws_eip" "one_vault" {
vpc = true
network_interface = "${aws_network_interface.same.id}"
associate_with_private_ip = "10.0.1.232"
}
resource "aws_network_interface" "same_ip" {
subnet_id = "subnet-567uhbnmkiu"
private_ips = ["10.0.1.16"]
}
resource "aws_launch_configuration" "launch_config" {
image_id = "${var.ami}"
key_name = "${var.keyname}"
}

You have to do it in your user data. https://forums.aws.amazon.com/thread.jspa?threadID=52601
#!/bin/bash
# configure AWS
aws configure set aws_access_key_id {MY_ACCESS_KEY}
aws configure set aws_secret_access_key {MY_SECRET_KEY}
aws configure set region {MY_REGION}
# associate Elastic IP
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
ALLOCATION_ID={MY_EIP_ALLOC_ID}
aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOCATION_ID --allow-reassociation

Terraform doesn't support this functionality as auto-scaling groups are managed by cloud provider like AWS, not by it.
For more details:
https://github.com/hashicorp/terraform/issues/7060

Related

Use acm certificate for lightsail instance via terraform

I have an ACM certificate already generate using terraform and used for an ECS load balancer. Now I have host a Wordpress website using Lightsail at the same domain, so I want reuse the same certficate public key but aws_acm_certificate doesn't expose it as output. So I found out I can get it using AWS CLI like:
aws acm get-certificate --certificate-arn {certificate:arn} --output text --query CertificateChain
I tried to pass the certificate to a aws_lightsail_key_pair but I am getting different errors. For example:
resource "null_resource" "write_acm_public_key" {
provisioner "local-exec" {
command = "aws acm get-certificate --certificate-arn ${aws_acm_certificate.default.arn} --output text --query CertificateChain > ${path.module}/acm-public-key.cert"
interpreter = ["/bin/bash", "-c"]
}
depends_on = [aws_acm_certificate.default]
}
data "local_file" "acm_public_key" {
filename = "${path.module}/acm-public-key.cert"
depends_on = [null_resource.write_acm_public_key]
}
resource "aws_lightsail_key_pair" "key" {
count = var.wp_enable ? 1 : 0
name = "${local.resource_prefix}-key"
public_key = data.local_file.acm_public_key.content
depends_on = [aws_acm_certificate.default, null_resource.write_acm_public_key, data.local_file.acm_public_key]
}
Says
No such file or directory
How can I reuse the same certificate?

How to get subnet_id of ec2 instances in AWS using Terraform?

Suppose we have some ec2 instances in AWS. How can we get subnet_ids of these ec2s via Terraform?
You should use a data source to fetch the existing EC2 instance and then just reference the data source and the attribute subnet_id where needed. Check the documentation: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/instance#subnet_id
Get the data related ec2 instances you want to get subnets of:
data "aws_instances" "ec2s" {
filter {
name = "tag:Name"
values = ["value"]
}
}
Get instance_id of each ec2 using count:
data "aws_instance" "ec2_subnets" {
count = length(data.aws_instances.ec2s.ids)
instance_id = data.aws_instances.ec2s.ids[count.index]
}
Now, subnets could be referred:
resource "aws_***" "***" {
count = length(data.aws_instance.ec2_subnets)
subnet_id = data.aws_instance.ec2_subnets[count.index].subnet_id
###
# Other Terraform attributes
###
}

setting hostname on multiple EC2 based on tags

I am running a terraform code to create multiple EC2 instances. Is there a way to setup the hostname of the instance based on tag and a domain name . Currently i login and run hostnamectl set-hostname ..
here is my tf script i use the create the instance.
resource "aws_instance" "RR-TEMP-V-DB" {
ami = var.linux_ami[var.region]
availability_zone = var.availability_zone
instance_type = var.temp_instance_type
key_name = var.linux_key_name
vpc_security_group_ids = [var.vpc_security_group_ids[var.region]]
subnet_id = var.db_subnet_id
count = var.temp_count
tags = {
Name = "RR-TEMP-V-DB-${format("%02d", count.index + 1)}"
Environment = var.env_tag
}
}
Thanks
We accomplish as part of user data, looks similar to:
instance_name=$(aws ec2 describe-instances --instance-id $(curl -s http://169.254.169.254/latest/meta-data/instance-id) --query "Reservations[*].Instances[*].Tags[?Key=='Name'].Value" --region $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e "s/.$//") --output text)
sudo hostnamectl set-hostname --static $instance_name
you can accomplish that with running as user data as #duhaas suggested or using remote-exec provisioner of terraform. here is the provisioner documentation of terraform, as you will see recommended way is setting user data on instance provision:
https://www.terraform.io/docs/provisioners/
for more details on remote-exec:
https://www.terraform.io/docs/provisioners/remote-exec.html

AWS Terraform target group for vpc endpoints

How can I create a target group for a network load balancer containing a VPC endpoint in Terraform?
In AWS console, I would have done following steps:
Create VPC Endpoint in two subnets to an endpoint service in another VPC
Create a target group of type IP and register the IP adresses of
the enpoints created in step 1
In terraform, I can create target groups and endpoints, but I don't know how to assign the enpoint's IPs to the target group. Where can I find instructions or an example how to do this? (Creating target groups for type instance is no problem, my question is specific for type IP).
Late to the party! But this is what I did.
Created a null resource that would get the IP addresses of the VPC endpoints and store it in a file
resource "null_resource" "nlb" {
triggers = {
always_run = "${timestamp()}"
}
provisioner "local-exec" {
command = "dig +short ${lookup(tomap(element(aws_vpc_endpoint.api-gw.dns_entry, 0)), "dns_name", "")} > /tmp/entry"
}
}
and then read the file entries
resource aws_lb_target_group_attachment nlb {
depends_on = [
null_resource.nlb
]
for_each = toset(slice(split("\n", file("/tmp/entry")), 0, 2))
target_group_arn = resource.aws_lb_target_group.nlb.arn
target_id = each.value
port = 443
}

provision EC2 in an existing VPC by providing an AWS Region using Terraform

I'm trying to provision an EC2 instance in an existing and specific VPC by providing an AWS region to Terraform.
I want to be able to automatically choose a specific vpc using regex or some other method, this is my tf file.
can anybody help me?
the VPC I want to be chosen automatically has a prefix "digital".
so instead of providing its name in here -> name = "tag:${local.env_profile}-vpc"
I want to provide only the region and then to get this specific VPC using regex.
provider "aws" {
region = "eu-west-3"
shared_credentials_file = "${var.shared_credentials_file}"
profile = "${var.profile}"
}
data "aws_vpc" "selected" {
filter {
name = "tag:${local.env_profile}-vpc"
values = ["${local.env_profile}-vpc"]
}
}
resource "aws_instance" "general" {
ami = "ami-00035f41c82244dab"
instance_type = "${var.type}"
vpc = "${data.aws_vpc.selected.id}"
key_name = "${var.key_name}"
tags {
Name = "empty"
}
}
I don't think there is a way to select a random VPC via regex in terraform. You can check the data source for VPC here https://www.terraform.io/docs/providers/aws/d/vpc.html
You can refer to a VPC . by using the ID and the name.