Terraform lookup AWS region - amazon-web-services

I have the following code in my main.tf file:
provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "us-east-1"
alias = "us-east-1"
}
provider "aws" {
access_key = "${var.aws_access_key}"
secret_key = "${var.aws_secret_key}"
region = "us-west-1"
alias = "us-west-1"
}
module "us-east_vpc" {
source = "./setup-networking"
providers = {
"aws.region" = "aws.us-east-1"
}
}
module "us-west_vpc" {
source = "./setup-networking"
providers = {
"aws.region" = "aws.us-west-1"
}
}
And then in my modules file I have:
provider "aws" {
alias = "region"
}
resource "aws_vpc" "default" {
provider = "aws.region"
cidr_block = "${lookup(var.vpc_cidr, ${aws.region.region})}"
enable_dns_hostnames = true
tags {
Name = "AWS VPC"
}
}
resource "aws_internet_gateway" "default" {
provider = "aws.region"
vpc_id = "${aws_vpc.default.id}"
}
resource "aws_subnet" "default" {
provider = "aws.region"
vpc_id = "${aws_vpc.default.id}"
cidr_block = "${lookup(var.subnet_cidr, ${aws.region.region})}"
availability_zone = "aws.region"
tags {
Name = "AWS Subnet"
}
}
resource "aws_route_table" "default" {
provider = "aws.region"
vpc_id = "${aws_vpc.default.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.default.id}"
}
tags {
Name = "Main Gateway"
}
}
As you can see in the modules file code I am trying to do a lookup to find the VPC CIDR mask and the subnet CIDR mask from map variables.
The trouble is that I can't seem to sort out how to get the region to be used as a lookup value.
If I hard code these values:
cidr_block = "10.10.0.0/16"
cidr_block = "10.10.10.0/24"
The script works as expected but I don't want to hard code the values.
Can someone with more Terraform experience help me understand how I can properly reference the region to lookup the correct value?

I was looking for the same answer for a different problem. I wanted to get the region for a name of a role, I was able to get the info by doing this:
1.- Create a file like data.tf and add this info:
data "aws_region" "current" {}
2.- Get the info from the data by calling this variable in any TF file:
name = "${var.vpc-name}-${data.aws_region.current.name}-Bastion-Role"
This way it will get the region where you are executing the code, and you don't have to mess with the provider.tf file.

You can get the region that's currently in use by the provider by using the aws_region data source.
So in your case you could do something like this:
provider "aws" {
alias = "region"
}
data "aws_region" "current" {
provider = "aws.region"
}
resource "aws_vpc" "default" {
provider = "aws.region"
cidr_block = "${lookup(var.vpc_cidr, ${data.aws_region.current.name})}"
enable_dns_hostnames = true
tags {
Name = "AWS VPC"
}
}
...

provider "aws" {
alias = "region"
}
data "aws_region" "current" {
provider = "aws.region"
}
data "aws_availability_zone" "current" {
provider = "aws.region"
name = "${data.aws_region.current.name}a"
}
resource "aws_vpc" "default" {
provider = "aws.region"
cidr_block = "${lookup(var.vpc_cidr, data.aws_availability_zone.current.name)}"
enable_dns_hostnames = true
tags {
Name = "${data.aws_region.current.name} Security VPC1"
Region = "${data.aws_region.current.name}"
Account = "Security"
}
}

Related

Terraform nat gateway AWS

I am trying to create nat gateway from terraform by using AWS as provider but subnet_id in resource aws_nat_gateway always gives me error. I am trying to assign public subnet in subnet_id on resource "aws_nat_gateway" "sample_nat_gateway" from variables.tf file but failing in doing so and need support if someone can assist ?
Below is my vpc.tf file of vpc module
resource "aws_subnet" "public-subnet" {
for_each = var.prefix
availability_zone_id = each.value["az"]
cidr_block = each.value["cidr"]
vpc_id = aws_vpc.sample_vpc.id
tags = {
Name = "${var.name}-${each.value["az"]}"
}
}
resource "aws_nat_gateway" "sample_nat_gateway" {
allocation_id = aws_eip.sample_eip.id
subnet_id = ""
tags = {
Name = "${var.name}-sample-nat-gateway"
Environment = var.environment
}
depends_on = [aws_internet_gateway.sample_igw]
}
variables.tf
variable "prefix" {
type = map
default = {
sub-1 = {
az = "use2-az1"
cidr = "10.0.1.0/16"
}
sub-2 = {
az = "use2-az2"
cidr = "10.0.2.0/24"
}
}
}
Subent's can't be empty You have to provide valid subnet id where the NAT is going to be placed. For example:
resource "aws_nat_gateway" "sample_nat_gateway" {
allocation_id = aws_eip.sample_eip.id
subnet_id = aws_subnet.public-subnet["sub-1"].id
tags = {
Name = "${var.name}-sample-nat-gateway"
Environment = var.environment
}
depends_on = [aws_internet_gateway.sample_igw]
}
where aws_subnet.example is one of the public subnets in your VPC.

Problems in creating aws route table using terraform

Running terraform v1.0.9 with AWS plugin v3.63.0 on a mac
Following hashicorp instructions for creating a route table (https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route_table), but getting the following error:
Error: Incorrect attribute value type
...
Inappropriate value for attribute "route": element 0: attributes "carrier_gateway_id", "destination_prefix_list_id", "egress_only_gateway_id",
│ "instance_id", "ipv6_cidr_block", "local_gateway_id", "nat_gateway_id", "network_interface_id", "transit_gateway_id", "vpc_endpoint_id", and
│ "vpc_peering_connection_id" are required.
Here is my main.tf:
provider "aws" {
region = "us-east-1"
}
resource "aws_vpc" "my-test-vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "my-test-vpc"
}
}
resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.my-test-vpc.id
}
resource "aws_route_table" "prod-route-table" {
vpc_id = aws_vpc.my-test-vpc.id
route = [
{
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}
]
tags = {
Name = "production"
}
}
I have run into something similar, without getting to the bottom of the root cause, so this is not the best possible answer, but moving the route out into its own explicit resource works for me:
resource "aws_route_table" "prod-route-table" {
vpc_id = aws_vpc.my-test-vpc.id
tags = {
Name = "production"
}
}
resource "aws_route" "prod-route-igw" {
route_table_id = aws_route_table.prod-route-table.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
depends_on = [aws_route_table.prod-route-table]
}

terraform: aws_route_table_association error

Error: Error creating route table association: InvalidRouteTableID.NotFound: The routeTable ID 'rtb-0208e6570f55bc571' does not exist status code: 400, request id: ecc6960b-2351-4603-add2-60e30ca77e10
But i am able to associate it without any issue manually. It is failing only with "rt_assocation_oregon" resource.
Full code:
#Create VPC in us-east-1
provider "aws" {
region = "us-east-1"
profile = " test1"
}
#Create VPC in us-west-2
provider "aws" {
region = "us-west-2"
profile = "test1"
alias = "west"
}
#Create VPC in us-east-1
resource "aws_vpc" "vpc_master" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "master-vpc-jenkins"
}
}
resource "aws_vpc" "vpc_master_oregon" {
cidr_block = "192.168.0.0/16"
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
provider = aws.west
tags = {
Name = "worker-vpc-jenkins"
}
}
#Create IGW in us-east-1
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc_master.id
tags = {
Name = "master_igw"
}
}
#Create IGW in us-west-2
resource "aws_internet_gateway" "igw-oregon" {
vpc_id = aws_vpc.vpc_master_oregon.id
provider = aws.west
tags = {
Name = "worker_igw"
}
}
#Create subnet # 1 in us-east-1
resource "aws_subnet" "subnet_1" {
vpc_id = aws_vpc.vpc_master.id
cidr_block = "10.0.1.0/24"
availability_zone = data.aws_availability_zones.available.names[0]
tags = {
Name = "master_subnet1"
}
}
#Create subnet in us-west-2
resource "aws_subnet" "subnet_oregon_1" {
vpc_id = aws_vpc.vpc_master_oregon.id
cidr_block = "192.168.1.0/24"
provider = aws.west
tags = {
Name = "worker_subnet1"
}
}
#Initiate Peering connection request from us-east1
resource "aws_vpc_peering_connection" "useast1_uswest2" {
peer_vpc_id = aws_vpc.vpc_master_oregon.id
vpc_id = aws_vpc.vpc_master.id
auto_accept = false
peer_region = "us-west-2"
tags = {
Name = "VPC Peering between vpc_master and vpc_master_oregon"
}
}
#Accept VPC peering request in us-west-2 from us-east-1
resource "aws_vpc_peering_connection_accepter" "accepter_peering" {
provider = aws.west
vpc_peering_connection_id = aws_vpc_peering_connection.useast1_uswest2.id
auto_accept = true
tags = {
Side = "Receiver"
}
}
#Create route table in us-east-1
resource "aws_route_table" "internet_route" {
vpc_id = aws_vpc.vpc_master.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
route {
cidr_block = "192.168.1.0/24"
vpc_peering_connection_id = aws_vpc_peering_connection.useast1_uswest2.id
}
lifecycle {
ignore_changes = all
}
tags = {
Name = "Master-Region-RT"
}
}
resource "aws_route_table_association" "rt_assocation_east" {
subnet_id = aws_subnet.subnet_1.id
route_table_id = aws_route_table.internet_route.id
}
#Create route table in us-west-2
resource "aws_route_table" "internet_route_oregon" {
provider = aws.west
vpc_id = aws_vpc.vpc_master_oregon.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw-oregon.id
}
route {
cidr_block = "10.0.1.0/24"
vpc_peering_connection_id = aws_vpc_peering_connection.useast1_uswest2.id
}
lifecycle {
ignore_changes = all
}
tags = {
Name = "Worker-Region-RT"
}
}
resource "aws_route_table_association" "rt_association_oregon" {
subnet_id = aws_subnet.subnet_oregon_1.id
route_table_id = aws_route_table.internet_route_oregon.id
}
Your aws_subnet.subnet_oregon_1 and aws_route_table.internet_route_oregon are created in us-west-2, but you are trying to create association in us-west-1. It should be:
resource "aws_route_table_association" "rt_association_oregon" {
provider = aws.west
subnet_id = aws_subnet.subnet_oregon_1.id
route_table_id = aws_route_table.internet_route_oregon.id
}

Terraform using output from module

I just started with Terraform infrastructure. Trying to create a vpc module that will contain code for vpc, subnets, internet gateway, rout table. Also creating a separate tf file for rds , which will refer to the vpc module and utilize the private subnets declared in vpc module.
Created a vpc module that has vpc.tf with following
provider "aws" {
region = var.region
}
terraform {
backend "s3" {}
}
resource "aws_vpc" "production-vpc" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
tags = {
Name = "Dev-VPC"
}
}
// Private Subnets
resource "aws_subnet" "private-subnet-1" {
cidr_block = var.private_subnet_1_cidr
vpc_id = aws_vpc.production-vpc.id
availability_zone = "us-east-1a"
tags = {
Name = "Private-Subnet-1"
}
}
resource "aws_subnet" "private-subnet-2" {
cidr_block = var.private_subnet_2_cidr
vpc_id = aws_vpc.production-vpc.id
availability_zone = "us-east-1b"
tags = {
Name = "Private-Subnet-2"
}
}
The output.tf has following
output "private-subnet1-id" {
description = "Private Subnet1 Id"
value = aws_subnet.private-subnet-1.*.id
}
output "private-subnet2-id" {
description = "Private Subnet2 Id"
value = aws_subnet.private-subnet-2.*.id
}
The file is saved in folder \module\vpc folder
Created rds.tf as follows in folder \rds
provider "aws" {
region = var.region
}
terraform {
backend "s3" {}
}
module "vpc" {
source = "../module/vpc"
}
resource "aws_db_subnet_group" "subnetgrp" {
name = "dbsubnetgrp"
subnet_ids = [module.vpc.private-subnet1-id.id, module.vpc.private-subnet2-id.id]
}
When I run terraform plan , I get following error
Error: Unsupported attribute
on rds.tf line 16, in resource "aws_db_subnet_group" "subnetgrp":
16: subnet_ids = [module.vpc.private-subnet1-id.id, module.vpc.private-subnet2-id.id]
|----------------
| module.vpc.private-subnet1-id is tuple with 1 element
This value does not have any attributes.
Error: Unsupported attribute
on rds.tf line 16, in resource "aws_db_subnet_group" "subnetgrp":
16: subnet_ids = [module.vpc.private-subnet1-id.id, module.vpc.private-subnet2-id.id]
|----------------
| module.vpc.private-subnet2-id is tuple with 1 element
This value does not have any attributes.
You don't need the splat expression in the output.tf. Try the following,
output "private-subnet1-id" {
description = "Private Subnet1 Id"
value = aws_subnet.private-subnet-1.id
}
output "private-subnet2-id" {
description = "Private Subnet2 Id"
value = aws_subnet.private-subnet-2.id
}

A managed resource "aws_internet_gateway" "igw_id" has not been declared in module.eip

I'm trying create eip and natgateway using terraform but i'm facing follwing error.
Error: Reference to undeclared resource
on ../../modules/eip/main.tf line 7, in resource "aws_eip" "nat-gateway":
7: depends_on = [aws_internet_gateway.igw_id]
A managed resource "aws_internet_gateway" "igw_id" has not been declared in
module.eip.
Here is my main.tf
variable "igw_id" {}
resource "aws_nat_gateway" "nat-gateway" {
allocation_id = "*********"
subnet_id = "*********"
depends_on = [aws_internet_gateway.igw_id]
tags {
Name = "*********"
Service = "*********"
Environment = terraform.workspace
}
}
Can anyone help me?
Here is my igw.tf
resource "aws_internet_gateway" "igw" {
vpc_id = "********"
tags = {
Name = "*********"
Service = "*********"
Environment = terraform.workspace
}
}
output.tf
output igw_id {
value = aws_internet_gateway.igw.id
}