Assign static IP address to a new aws instance using terraform - amazon-ec2

I already have static IP address but i am trying to assign this IP address to newly create instance by using terraform but unfortunately i am getting new Ip address. Can somebody help?
data "aws_eip" "my_instance_eip" {
public_ip ="3.17.21.34"
}
resource "aws_instance" "Webserver_Instance" {
instance_type = var.type_webserver
ami = var.ami_webserver
key_name = var.key_name
tags = {
name = "Webserver_Instance"
}
security_groups = ["${aws_security_group.Webserver_SG.name}"]
}
resource "aws_eip_association" "my_eip_association" {
instance_id = aws_instance.Webserver_Instance.id
allocation_id = data.aws_eip.my_instance_eip.id
}

Related

Attach Elastic IP To Multiple EC2 Instances In Terraform

I am trying to attach Elastic IP to multiple EC2 Instances using terraform. I have been able to create EC2 instances , VPC and Security groups but getting error while attaching Elastic IP's to EC2 instances.
Resource AWS_Instance
resource "aws_instance" "create_instance" {
for_each = toset(var.instance_type)
ami = var.ami
instance_type = each.value
vpc_security_group_ids = [aws_security_group.vpc-ssh.id, aws_security_group.vpc-web.id]
availability_zone = var.availability_zone[index(var.instance_type,each.value)]
tags = {
"key" = each.value
}
}
I am not able to decode how should the instance id be populated inside the elastic IP resource definition.
Create Elastic IP
resource "aws_eip" "my-eip" {
for_each = toset(var.instance_type)
instance = aws_instance.create_instance[???].id // what should be used here
vpc = true
depends_on = [aws_internet_gateway.vpc-dev-igw] }
Since you are looping through the variable instance_type for both resources, you have to put each.value for referencing the EC2 instances:
resource "aws_eip" "my-eip" {
for_each = toset(var.instance_type)
instance = aws_instance.create_instance[each.value].id
vpc = true
depends_on = [aws_internet_gateway.vpc-dev-igw]
}

Terraform Throwing 'InvalidParameterValue' Address x.x.x.x does not fal within the subnet's address range.. it does

Having an issue with a Terraform deployment. I have a module that creates a network, and then another module that creates a series of ec2 instances. These servers are required to have specific IP addresses, which are called out in the module (I would rather dynamically set these but for now they are 'hardcoded'). However, I am getting a warning that the IP address I am associating with the ec2 instance 'does not fall within the subnet's address range', but it is. Here is the basic breakdown:
servers
->main.tf
->variables.tf
->outputs.tf
network
->main.tf
->variables.tf
->outputs.tf
main.tf
The relevant bits are as follows:
network main.tf
# Create VPC
resource "aws_vpc" "foo" {
cidr_block = "192.168.1.0/24"
enable_dns_hostnames = "true"
enable_dns_support = "true"
tags = {
Name = "foo"
}
}
# Create a Subnet
resource "aws_subnet" "subnet-1" {
vpc_id = aws_vpc.foo.id
cidr_block = "192.168.1.0/24"
availability_zone = "ca-central-1a"
tags = {
Name = "subnet-1"
}
}
servers main.tf
resource "aws_instance" "bar" {
ami = var.some_ami
instance_type = "t3.medium"
associate_public_ip_address = true
private_ip = "192.168.1.15"
# root disk
root_block_device {
volume_size = "60"
volume_type = "gp3"
encrypted = true
delete_on_termination = true
}
tags = {
Name = "bar"
}
}
main.tf
module "network" {
source = "./network"
}
module "servers" {
source = "./servers"
subnet_id = module.network.aws_subnet
}
Everything works correctly, and I verified in AWS that the VPC is created, and the subnet is created, but for some reason when the server is getting created I get the following error:
│ Error: creating EC2 Instance: InvalidParameterValue: Address 192.168.1.15 does not fall within the subnet's address range status code: 400
I left out some of the irrelevant bits of the tfs but everything else works as expected except this one thing. Anyone know whats going on?
Your aws_instance resource does not have subnet_id attribute. So instances are being launched in default subnet.
Add subnet_id attribute as below
resource "aws_instance" "bar" {
ami = var.some_ami
instance_type = "t3.medium"
associate_public_ip_address = true
subnet_id = "your_subnet_id"
private_ip = "192.168.1.15"
# root disk
root_block_device {
volume_size = "60"
volume_type = "gp3"
encrypted = true
delete_on_termination = true
}
tags = {
Name = "bar"
}
}
You could also use data resource to get the subnet id.
data "aws_subnet" "selected" {
filter {
name = "tag:Name"
values = ["myawesomesubnet"]
}
}

Terraform - Create ec2 instances in each availability zone

I am trying to create multiple ec2 instance with this script
resource "aws_instance" "my-instance" {
count = 3
ami = ...
instance_type = ...
key_name = ...
security_groups = ...
tags = {
Name = "my-instance - ${count.index + 1}"
}
}
This creates 3 instances. But all three are in same availability zones. I want to create one instance in each availability zone or one in each of the availability zone that I provide. How can I do it?
I read that I can use
subnet_id = ...
option to specify the availability zone where the instance should be created. But I am not able to figure out how to loop through instance creation (which is currently being handled by count parameter) and specifiy different subnet_id
Can someone help please.
There are several ways of accomplishing this. What I would recommend is to create a VPC with 3 subnets and place an instance in each subnet:
# Specify the region in which we would want to deploy our stack
variable "region" {
default = "us-east-1"
}
# Specify 3 availability zones from the region
variable "availability_zones" {
default = ["us-east-1a", "us-east-1b", "us-east-1c"]
}
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = var.region
}
# Create a VPC
resource "aws_vpc" "my_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "my_vpc"
}
}
# Create a subnet in each availability zone in the VPC. Keep in mind that at this point these subnets are private without internet access. They would need other networking resources for making them accesible
resource "aws_subnet" "my_subnet" {
count = length(var.availability_zones)
vpc_id = aws_vpc.my_vpc.id
cidr_block = cidrsubnet("10.0.0.0/16", 8, count.index)
availability_zone = var.availability_zones[count.index]
tags = {
Name = "my-subnet-${count.index}"
}
}
# Put an instance in each subnet
resource "aws_instance" "foo" {
count = length(var.availability_zones)
ami = ...
instance_type = "t2.micro"
subnet_id = aws_subnet.my_subnet[count.index].id
tags = {
Name = "my-instance-${count.index}"
}
}

How can I pass aws ec2 private ips to template file Using terraform

I am fairly new to terraform. I am trying to create number of ec2 instances and want to run bootstrap script once instance is ready, and in bootstrap script I need to pass private ips of instance created ( part of terraform script).
After so much of googling I came to know that I have to use terraform_file but, not able to use it correctly.
Terraform version: 0.11.13
/* Security group for the instances */
resource "aws_security_group" "test-reporting-sg"
{
name = "${var.environment}-test-reporting-sg"
vpc_id = "${var.vpc_id}"
}
data "template_file" "init"
{
count = "${var.instance_count}"
template = "${file("${path.module}/wrapperscript.sh")}"
vars = {
ip_addresses= "${aws_instance.dev-testreporting.*.private_ip}"
}
}
resource "aws_instance" "dev-testreporting"
{
count = "${var.instance_count}"
ami="${var.ami_id}"
instance_type ="${var.instance_type}"
key_name ="${var.key_name}"
security_groups = [ "${aws_security_group.test-reporting-sg.id}" ]
subnet_id = "${var.subnet_ids}"
user_data = "${data.template_file.init.*.rendered.[count.index]}"
}
Thanks
In resource module you can add private_ip like below
private_ip = "${lookup(var.private_ips,count.index)}"
and add private_ip values to variable file

Can I SSH into my EC2 instance created by terraform?

I have created an EC2 instance using terraform (I do not have the .pem keys). Can I establish an SSH connection between my local system and the EC2 instance?
Assuming you provisioned an instance using Terraform v0.12.+ with this structure:
resource "aws_instance" "instance" {
ami = "${var.ami}"
instance_type = "t2.micro"
count = 1
associate_public_ip_address = true
}
You can make some additional settings:
Configure the public ip output:
output "instance_ip" {
description = "The public ip for ssh access"
value = aws_instance.instance.public_ip
}
Create an aws_key_pair with an existing ssh public key or create a new one
Ex:
resource "aws_key_pair" "ssh-key" {
key_name = "ssh-key"
public_key = "ssh-rsa AAAAB3Nza............"
}
Add the key_name in instance resource just like this:
resource "aws_instance" "instance" {
ami = var.ami
instance_type = "t2.micro"
count = 1
associate_public_ip_address = true
key_name = "ssh-key"
}
Now you need to apply running terraform apply and terraform output to return the public IP
Get your public IP and run:
ssh <PUBLIC IP>
OR with a public key path
ssh -i "~/.ssh/id_rsa.pub" <PUBLIC IP>
Sources:
https://www.terraform.io/docs/providers/aws/r/instance.html
https://www.terraform.io/docs/providers/aws/r/key_pair.html
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html

Resources