Reputation: 199
I've a two modules under modules directory named as prienv and vpc
nnice@MPL-G8WW7D3:~/terra-test/modules/prienv$ pwd
/home/nnice/terra-test/modules/prienv
nnice@MPL-G8WW7D3:~/terra-test/modules/prienv$ ls
data.tf main.tf variable.tf
Here is my data.tf file under prienv module
nnice@MPL-G8WW7D3:~/terra-test/modules/prienv$ cat data.tf
data "aws_security_groups" "mysg-data" {
filter {
name = "tag:Name"
values = ["MySG"]
}
depends_on = [aws_security_groups.mysg]
}
data "aws_subnet" "myprisn-data" {
filter {
name = "tag:Name"
values = ["MyPriSN"]
}
depends_on = [aws_subnet.myprisn]
}
Here is my variable.tf file under prienv module
variable "pri_av" {
description = "for private availability zone"
type = string
default = "us-east-1b"
}
variable "ami" {
description = "ami for ec2"
type = string
default = "ami-03ededff12e34e59e"
}
variable "instance_type" {
description = "Instance type t2.micro"
type = string
default = "t2.micro" #will use double quotes for string type
}
variable "key_pair" {
description = "key pair for ec2"
type = string
default = "learner_key"
}
variable "instance_count" {
description = "EC2 instance count"
type = number
default = 1 #here we're using it to create two private instances
}
variable "project_environment" {
description = "project name and environment for private instances"
type = map(string)
default = {
project = "private", # it works upon key value pair where project is for key and environment is value
environment = "testing" # you will find them under tag on aws console
}
}
And this is my main.tf file under prienv module
resource "aws_instance" "mypriec2" {
ami = var.ami
instance_type = var.instance_type
count = var.instance_count
availability_zone = var.pri_av
#subnet_id = aws_subnet.myprisn.id
subnet_id = data.aws_subnet.myprisn-data.id
#vpc_security_group_ids = [aws_security_group.mysg.id]
vpc_security_group_ids = data.aws_security_groups.mysg-data.ids
key_name = var.key_pair
# disable_api_termination = true
tags = var.project_environment
}
resource "aws_key_pair" "mykeypair" {
key_name = var.key_pair
public_key = "ssh-rsa AAAAB3NaffrWscf59juCakElys9F3+zVuz0ta4gRUtKgWVPIj6ACr00VNDzsTTW2/sSjYtE5zWolVKCITlhqiIhgRKUDLKoxclxUKnK6IGIafdaefafaheiufa;fdaeoasfdkQvNtGrrHzY5/dbZhIUTxDUyvT5O5U= nnice@MPL-G8WW7D3"
}
and here is my vpc moduls
nnice@MPL-G8WW7D3:~/terra-test/modules/vpc$ pwd
/home/nnice/terra-test/modules/vpc
nnice@MPL-G8WW7D3:~/terra-test/modules/vpc$ ls
data.tf main.tf variable.tf
This is my data.tf file under vpc module
nnice@MPL-G8WW7D3:~/terra-test/modules/vpc$ cat data.tf
data "aws_vpc" "myvpc-data" {
filter {
name = "tag:Name"
values = ["MyVPC"]
}
depends_on = [aws_vpc.myvpc]
}
data "aws_subnet" "mypubsn-data" {
filter {
name = "tag:Name"
values = ["MyPubSN"]
}
depends_on = [aws_subnet.mypubsn]
}
data "aws_subnet" "myprisn-data" {
filter {
name = "tag:Name"
values = ["MyPriSN"]
}
depends_on = [aws_subnet.myprisn]
}
This is my main.tf file under vpc module
nnice@MPL-G8WW7D3:~/terra-test/modules/vpc$ cat main.tf
##################################################################
############################## VPC ###############################
##################################################################
resource "aws_vpc" "myvpc" {
cidr_block = var.vpc_cidr
instance_tenancy = var.vpc_tenancy
tags = {
Name = var.vpc_tag
}
}
##################################################################
############################# Subnet #############################
##################################################################
#PUBLIC SUBNET
resource "aws_subnet" "mypubsn" {
#vpc_id = aws_vpc.myvpc.id
vpc_id = data.aws_vpc.myvpc-data.id
cidr_block = var.mypubsn_cidr
availability_zone = var.pub_av
map_public_ip_on_launch = var.map_public_ip_on_launch
tags = {
Name = var.mypubsn_tag
}
}
#PRIVATE SUBNET
resource "aws_subnet" "myprisn" {
#vpc_id = aws_vpc.myvpc.id
vpc_id = data.aws_vpc.myvpc-data.id
cidr_block = var.myprisn_cidr
availability_zone = var.pri_av
tags = {
Name = var.myprisn_tag
}
}
##################################################################
############################### IGW ##############################
##################################################################
resource "aws_internet_gateway" "myigw" {
#vpc_id = aws_vpc.myvpc.id
vpc_id = data.aws_vpc.myvpc-data.id
tags = {
Name = var.igw_tag
}
}
##################################################################
############################ Route Table #########################
##################################################################
#PUBLIC RT
resource "aws_route_table" "mypubrt" {
#vpc_id = aws_vpc.myvpc.id
vpc_id = data.aws_vpc.myvpc-data.id
tags = {
Name = var.mypubsn_tag
}
}
#PRIVATE RT
resource "aws_route_table" "myprirt" {
#vpc_id = aws_vpc.myvpc.id
vpc_id = data.aws_vpc.myvpc-data.id
tags = {
Name = var.myprisn_tag
}
}
####################################################################
######################## Route Table Associate #####################
####################################################################
#PUBLIC RT association
resource "aws_route_table_association" "pub" {
#subnet_id = aws_subnet.mypubsn.id
subnet_id = data.aws_subnet.mypubsn-data.id
route_table_id = aws_route_table.mypubrt.id
}
#PRIVATE RT association
resource "aws_route_table_association" "pri" {
#subnet_id = aws_subnet.myprisn.id
subnet_id = data.aws_subnet.myprisn-data.id
route_table_id = aws_route_table.myprirt.id
}
###################################################################
########################### Route #################################
###################################################################
#PUBLIC Route
resource "aws_route" "mypubroute" {
route_table_id = aws_route_table.mypubrt.id
destination_cidr_block = var.pubroute
gateway_id = aws_internet_gateway.myigw.id
depends_on = [aws_route_table.mypubrt]
}
#PRIVATE Route
#resource "aws_route" "mypriroute" {
# route_table_id = aws_route_table.myprirt.id
# destination_cidr_block = "0.0.0.0/0"
# gateway_id = aws_internet_gateway.myigw.id
# depends_on = [aws_route_table.myprirt]
#}
###################################################################
############################ SG ###################################
###################################################################
resource "aws_security_group" "mysg" {
name = "MySecurityGroup"
description = "Allow TLS inbound traffic"
#vpc_id = aws_vpc.myvpc.id
vpc_id = data.aws_vpc.myvpc-data.id
ingress {
description = "TLS from VPC"
from_port = 22
to_port = 22
protocol = "tcp"
# cidr_blocks = [aws_vpc.myvpc.cidr_block]
cidr_blocks = ["0.0.0.0/0"]
# ipv6_cidr_blocks = [aws_vpc.main.ipv6_cidr_block]
}
ingress {
description = "TLS from VPC"
from_port = 80
to_port = 80
protocol = "tcp"
# cidr_blocks = [aws_vpc.myvpc.cidr_block]
cidr_blocks = ["0.0.0.0/0"]
# ipv6_cidr_blocks = [aws_vpc.main.ipv6_cidr_block]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = var.SG_tag
}
}
And this is my variable.tf file under vpc module
nnice@MPL-G8WW7D3:~/terra-test/modules/vpc$ cat variable.tf
variable "vpc_tenancy" {
description = "vpc instance tenancy"
type = string
default = "default"
}
variable "pub_av" {
description = "for public availability zone"
type = string
default = "us-east-1a"
}
variable "pri_av" {
description = "for private availability zone"
type = string
default = "us-east-1b"
}
variable "vpc_tag" {
description = "Tag for VPC"
type = string
default = "MyVPC"
}
variable "vpc_cidr" {
description = "for vpc cidr"
type = string
default = "10.0.0.0/16"
}
variable "mypubsn_cidr" {
description = "for public subnet cidr"
type = string
default = "10.0.1.0/24"
}
variable "myprisn_cidr" {
description = "for private subnet cidr"
type = string
default = "10.0.2.0/24"
}
variable "mypubsn_tag" {
description = "tag for public subnet"
type = string
default = "MyPubSN"
}
variable "myprisn_tag" {
description = "tag for private subnet"
type = string
default = "MyPriSN"
}
variable "igw_tag" {
description = "tag for IGW subnet"
type = string
default = "MyIGW"
}
variable "pubrt_tag" {
description = "tag for private subnet"
type = string
default = "MyPubRT"
}
variable "prirt_tag" {
description = "tag for IGW subnet"
type = string
default = "MyPriRT"
}
variable "pubroute" {
description = "cidr for public route"
type = string
default = "0.0.0.0/0"
}
variable "SG_tag" {
description = "tag for SG"
type = string
default = "MySG"
}
variable "map_public_ip_on_launch" {
description = "auto enable public ip to public subnet"
type = bool
default = true
}
And there is env directory where I have my main.tf file
nnice@MPL-G8WW7D3:~/terra-test$ ls
env modules
nnice@MPL-G8WW7D3:~/terra-test$ cd env/private-ec2/
nnice@MPL-G8WW7D3:~/terra-test/env/private-ec2$ pwd
/home/nnice/terra-test/env/private-ec2
nnice@MPL-G8WW7D3:~/terra-test/env/private-ec2$ ls
main.tf
nnice@MPL-G8WW7D3:~/terra-test/env/private-ec2$ cat main.tf
#Provider
provider "aws" {
region = "us-east-1"
}
#VPC
module "vpc" {
source = "../../modules/vpc"
}
#EC2
module "prienv" {
source = "../../modules/prienv"
}
When I'm trying to run terraform plan, I'm getting following errors
Error: Reference to undeclared resource
│
│ on ../../modules/prienv/data.tf line 6, in data "aws_security_groups" "mysg-data":
│ 6: depends_on = [aws_security_groups.mysg]
│
│ A managed resource "aws_security_groups" "mysg" has not been declared in module.prienv.
╵
╷
│ Error: Reference to undeclared resource
│
│ on ../../modules/prienv/data.tf line 14, in data "aws_subnet" "myprisn-data":
│ 14: depends_on = [aws_subnet.myprisn]
│
│ A managed resource "aws_subnet" "myprisn" has not been declared in module.prienv.
Could anyone please let me know its solution? I already using vpc module in my main.tf file
Upvotes: 1
Views: 9227
Reputation: 762
The issue you are running into is that aws_security_groups.mysg
and aws_subnet.myprisn
are locally defined in the vpc module but you are referencing them in the depends_on
statement in the prienv module.
Also the Terraform documentation suggests that the depends_on
argument
should be used only as a last resort.
So the way to go would be, to define the security group and the subnet as an output in the vpc module, as variable in the prienv module, and then passing the outputs of vpc as parameter values to prienv.
This way terraform will recognize the dependencies between the resources from the dependency graph it creates and you won't neet the depends_on
argument.
So in consequence, the diffs to your config could look like:
modules/vpc/outputs.tf
output "sec_group" {
value = aws_security_group.mysg
description = "..."
}
output "subnet" {
value = aws_subnet.myprisn
description = "..."
}
modules/prienv/variable.tf
variable "sec_group" {
description = "..."
}
variable "subnet" {
description = "..."
}
modules/prienv/main.tf
resource "aws_instance" "mypriec2" {
...
subnet_id = var.subnet.id
vpc_security_group_ids = var.sec_group.ids
...
}
env/main.tf
module "vpc" {
source = "../../modules/vpc"
}
#EC2
module "prienv" {
source = "../../modules/prienv"
sec_group = module.vpc.sec_group
subnet = module.vpc.subnet
}
Upvotes: 2