I'm getting the following error running Terraform apply
when trying to reference an output from another Module:
│ Error: Unsupported attribute
│
│ on ../app-db-modules/rds.tf line 14, in resource "aws_db_subnet_group" "ccDBSubnetGroup":
│ 14: subnet_ids = ["${data.terraform_remote_state.remote.outputs.ccPrivateSubnetId}"]
│ ├────────────────
│ │ data.terraform_remote_state.remote.outputs is object with no attributes
│
│ This object does not have an attribute named "ccPrivateSubnetId".
╵
Tree
.
├── app
│ ├── main.tf
│ ├── terraform.tfstate
│ └── terraform.tfstate.backup
├── app-db-modules
│ ├── main.tf
│ ├── rds.tf
│ └── variables.tf
├── app-network-modules
│ ├── main.tf
│ ├── outputs.tf
│ ├── variables.tf
│ └── vpc.tf
└── app-tf-state-infra-modules
├── main.tf
├── tf-state-infra.tf
└── variables.tf
main.tf (app dir)
terraform {
backend "s3" {
bucket = "MY_BUCKET_NAME"
key = "tf-infra/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-state-locking"
encrypt = true
}
required_providers {
aws = {
source = "hashicorp/aws"
version = "~>3.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
...
module "vpc-infra" {
source = "../app-network-modules"
# VPC Input Vars
vpc_cidr = "10.0.0.0/16"
public_subnet_cidr = "10.0.0.0/24"
private_subnet_cidr = "10.0.1.0/24"
}
module "rds-infra" {
source = "../app-db-modules"
# RDS Input Vars
db_az = "us-east-1a"
db_name = "ccDatabaseInstance"
db_user_name = var.db_user_name
db_user_password = var.db_user_password
}
vpc.tf (app-network-modules)
...
resource "aws_subnet" "ccPrivateSubnet" {
vpc_id = aws_vpc.ccVPC.id
cidr_block = var.private_subnet_cidr
}
...
outputs.tf (app-network-modules)
output "ccPrivateSubnetId" {
description = "Will be used by rds Module to set subnet_ids"
value = aws_subnet.ccPrivateSubnet.id
}
The following {data.terraform_remote_state.remote.outputs.ccPrivateSubnetId}
is causing the error:
rds.tf (app-db-modules)
data "terraform_remote_state" "remote" {
backend = "s3"
config = {
bucket = "MY_BUCKET_NAME"
key = "tf-infra/terraform.tfstate"
region = "us-east-1"
}
}
resource "aws_db_subnet_group" "ccDBSubnetGroup" {
subnet_ids = ["${data.terraform_remote_state.remote.outputs.ccPrivateSubnetId}"]
}
resource "aws_db_instance" "ccDatabaseInstance" {
db_subnet_group_name = "ccDBSubnetGroup"
availability_zone = var.db_az
allocated_storage = 20
storage_type = "standard"
engine = "postgres"
engine_version = "12.5"
instance_class = "db.t2.micro"
name = var.db_name
username = var.db_user_name
password = var.db_user_password
skip_final_snapshot = true
}
output "all_outputs" {
value = data.terraform_remote_state.remote.outputs
}
Any thoughts on why data.terraform_remote_state.remote.outputs is object with no attributes
and/or why I'm unable to reference the ccPrivateSubnetId
in rds.tf
which was provided as output from another Module (vpc.tf
) would be appreciated!
EDITing to provide solution based on comments provided below.
main.tf
...
module "vpc-infra" {
source = "../app-network-modules"
# VPC Input Vars
vpc_cidr = "10.0.0.0/16"
public_subnet_cidr = "10.0.0.0/24"
private_subnet_cidr = "10.0.1.0/24"
}
module "rds-infra" {
source = "../app-db-modules"
# RDS Input Vars
ccPrivateSubnetId = "${module.vpc-infra.ccPrivateSubnetId}"
db_az = "us-east-1a"
db_name = "ccDatabaseInstance"
db_user_name = var.db_user_name
db_user_password = var.db_user_password
}
...
outputs.tf
output "ccPrivateSubnetId" {
description = "Will be used by RDS Module to set subnet_ids"
value = "${aws_subnet.ccPrivateSubnet.id}"
}
vpc.tf
...
resource "aws_subnet" "ccPrivateSubnet" {
vpc_id = aws_vpc.ccVPC.id
cidr_block = var.private_subnet_cidr
}
...
rds.tf
resource "aws_db_subnet_group" "ccDBSubnetGroup" {
subnet_ids = ["${var.ccPrivateSubnetId}"]
}
...
Using data.terraform_remote_state
in general is bad practice. I would call it a very advanced feature that should only be used in extreme edge cases. If you are referencing the same state that the current Terraform template is using, then it is an absolute anti-pattern.
Instead, make the values you need to reference part of the outputs of the network module, then pass those values as inputs to the DB module.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments