aws_db_instance doesn't detect aws_db_subnet_group dependecy

974 views
Skip to first unread message

Javier Ruiz Jiménez

unread,
Feb 12, 2018, 5:54:14 PM2/12/18
to Terraform
I am creating a full AWS VPC using Terraform and have found an issue with RDS instances and DB sub net groups that don't see the dependency.

Terraform v0.11.2
+ provider.aws v1.9.0
+ provider.external v1.0.0

All my resources are created using modules.

aws_db_instance has an optional parameter db_subnet_group_name. If specified DB instance will be created in the VPC associated with the DB subnet group. It is a name, not an ID.

Terraform starts the creation of the DB Subnet group:

module.aws_rds_sn_pro_01.aws_db_subnet_group.default: Creating...
  arn
:                   "" => "<computed>"
  description
:           "" => "ditwl-RDS-SN-PRO-01"
  name
:                  "" => "ditwl-rds-sn-pro-01"
  name_prefix
:           "" => "<computed>"
  subnet_ids
.#:          "" => "2"
  subnet_ids
.144929211:  "" => "subnet-67a1ec48"
  subnet_ids
.1758656648: "" => "subnet-7dffcf19"
  tags
.%:                "" => "1"
  tags
.Name:             "" => "ditwl-rds-sn-pro-01"

And creation of the DB Instance right after, without waiting for the aws_rds_sn_pro_01 creation complete:

module.aws_rds_pro_mariadb_01.aws_db_instance.default: Creating...
  address
:                           "" => "<computed>"
  db_subnet_group_name
:              "" => "ditwl-rds-sn-pro-01"

 
...
module.aws_rds_sn_pro_01.aws_db_subnet_group.default: Creation complete after 2s (ID: ditwl-rds-sn-pro-01)

module.aws_ec2_pro_wp.aws_instance.default: Still creating... (10s elapsed)


Error

An error is produced as the DB creation starts before the DB Subnet group creation is complete.

Error: Error applying plan:

1 error(s) occurred:

* module.aws_rds_pro_mariadb_01.aws_db_instance.default: 1 error(s) occurred:
* aws_db_instance.default: Error creating DB Instance: InvalidVPCNetworkStateFault: A VPC associated with the DB subnet group ditwl-rds-sn-pro-01 does not exist. . Update the DB subnet group and try again
 status code
: 400, request id: 8b43ec7d-1d16-424f-80c8-26c564a4ac81


The plan succeeds on the second run, as the DB Subnet group has already been created.

Source code

My aws_db_instance is created with this call to the module:

module "aws_rds_pro_mariadb_01" {
  source
= "./modules/aws/rds/instance"
  identifier              
= "${var.aws_rds_pro_mariadb_01["identifier"]}"
   
....
  db_subnet_group_name    
= "${var.aws_rds_sn_pro_01["name"]}"
 
...
}

The module /modules/aws/rds/instance:

resource "aws_db_instance" "default" {
  identifier                
= "${var.identifier}"
 
...
  db_subnet_group_name      
= "${var.db_subnet_group_name}"
 
...
}

The DB Subnet is created in another module:

module "aws_rds_sn_pro_01" {
    source      
= "./modules/aws/rds/subnet"
    name        
= "${var.aws_rds_sn_pro_01["name"]}"
    description
= "${var.aws_rds_sn_pro_01["description"]}"
    subnet_ids  
= "${module.aws_sn_za_pro_pub_32.id},${module.aws_sn_zb_pro_pub_36.id}"
}


The module /modules/aws/rds/subnet:
resource "aws_db_subnet_group" "default" {
  name        
= "${var.name}"
  description
= "${var.description}"
  subnet_ids  
= ["${split(",", var.subnet_ids)}"]
  tags
{
   
Name = "${var.name}"
 
}
}


I believe Terraform doesn't see the dependency as the db_subnet_group_name is a variable. 

I have not been able to find a way to explicit declare the dependency as Terraform doesn't allow interpolations on depends_on, for example:

resource "aws_db_instance" "default" {
  identifier                
= "${var.identifier}"
 
...
  db_subnet_group_name      
= "${var.db_subnet_group_name}"
 
...
 depends_on
= ["${var.dependency}"] # <--Variable could have a value of module.aws_rds_sn_pro_01
}


A temporary workaround that has worked so far, has been to use the output id of aws_rds_sn_pro_01 as an input to the aws_db_instance creation and using that value as a tag so that the resource "aws_db_instance" has to wait for the value.


resource
"aws_db_instance" "default" {
  identifier                
= "${var.identifier}"
 
...
  db_subnet_group_name      
= "${var.db_subnet_group_name}"
 
...
   tags = "${merge(map("Name", format("%s-%d", var.identifier, count.index+1)),
    var.instance_tags,
    map("private_name", var.tag_private_name),
    ....
    map("db_subnet_group_id", var.db_subnet_group_id) #<--- Uses db_subnet_group_id that contains a reference to the DB Subnet ID "${module.aws_rds_sn_pro_01.id}"
   )}"
}

Will greatly appreciate your help.

Thanks
Javier















Javier Ruiz Jiménez

unread,
Feb 12, 2018, 6:16:51 PM2/12/18
to Terraform

I see that the ID returned by aws_db_subnet_group is the same as the name of the DB Subnet group, so I could use that output as a dependency for the value of db_subnet_group_name, but then probably the aws_db_instance parameter should be named db_subnet_group_id for documentation clarification. right?

⁞ Fernando Miguel

unread,
Feb 13, 2018, 1:47:58 AM2/13/18
to terrafo...@googlegroups.com
It's probably one of the most challenging things to work with terraform 
It doesn't expand the graph when working with modules nor it allows for explicit dependencies on other modules. 

The process I've been following is to have a second stage state file, that reads the 1st run as external data source. 

Another alternative is to run apply against only parts of the state allowing it to build the things you need first. 

An uglier option is for your module to manage all of the resources inside it and not have several modules resources. 

--
Fernando Miguel

--
This mailing list is governed under the HashiCorp Community Guidelines - https://www.hashicorp.com/community-guidelines.html. Behavior in violation of those guidelines may result in your removal from this mailing list.
 
GitHub Issues: https://github.com/hashicorp/terraform/issues
IRC: #terraform-tool on Freenode
---
You received this message because you are subscribed to the Google Groups "Terraform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to terraform-tool+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/terraform-tool/8a8ea613-ceec-4740-993d-e0d4e324ff22%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Clint Shryock

unread,
Feb 13, 2018, 1:08:23 PM2/13/18
to terrafo...@googlegroups.com

Hello all –


>It doesn't expand the graph when working with modules nor it allows for explicit dependencies on other modules. 


I’m not sure that’s correct, Terraform should absolutely be able to have dependencies on other modules. I’d like to know a bit more about the above configuration. Can you show how `var.aws_rds_sn_pro_01` is defined? 


Javier – I believe your suspicion is correct. At first glance, it appears both the name provided to the DB Subnet Module and the name provided the DB Instance Module (usedfor the db subnet name) are both `"${var.aws_rds_sn_pro_01["name”]}`. This tells me that the name is set, and is essentially static at the time Terraform constructs the graph. Assuming this is true, then Terraform correctly doesn’t mark the DB Instance to depend on the DB Subnet being created first, instead they both simply depend on the `aws_rds_sn_pro_01["name”]` value being set. 


In this case, the dependency graph looks essentially like so:




​​


With this graph, Terraform is free to create both db_subnet and db_instance in parallel.
I believe the solution then is to make sure that the DB Subnet Module `aws_rds_sn_pro_01` outputs the db subnet name:


```

#called ‘named’ here simply because the db subnet group name is also it’s ID in state 

output “db_subnet_group_nameid” {

  value = "${aws_db_subnet_group.default.id}”

}

```


The DB Instance Module should then be changed to use the DB Subnet Module’s output, and not use the common 

`aws_rds_sn_pro_01["name”]` value:


```

module "aws_rds_pro_mariadb_01" {

  source = "./modules/aws/rds/instance"

  identifier              = "${var.aws_rds_pro_mariadb_01["identifier"]}"

   ....

  db_subnet_group_name    = “${module.aws_rds_sn_pro_01.db_subnet_group_nameid}”

  ...

}

```


This setup should instruct Terraform to generate a graph with dependencies in order; Terraform will know that the input for the DB Instance Module requires the output of the DB Subnet Module, and the graph changes to look like so:






Here, the module.db_instance can't proceed until db_subnet is complete, and module.db_subnet outputs the value.

Both graphs are generalizations of course. To make them I used http://www.webgraphviz.com . The values used are shown below.


Let me know if this helps! 


Cheers,

Clint



Graph 1 values:


digraph G {

  "root" -> "var.name"

  "var.name" -> "module.db_subnet"

  "var.name" -> "module.db_instance"

  "module.db_instance" -> "db_instance"

  "module.db_subnet" -> "db_subnet"

}


Graph 2 values:


digraph G {

  "root" -> "var.name"

  "var.name" -> "module.db_subnet"

  "module.db_subnet" -> "db_subnet"

  "module.db_subnet" -> "module.db_instance"

  "db_subnet" -> "module.db_instance"

  "module.db_instance" -> "db_instance"

}


⁞ Fernando Miguel

unread,
Feb 13, 2018, 1:10:12 PM2/13/18
to terrafo...@googlegroups.com
 Terraform should absolutely be able to have dependencies on other modules.

Clint Shryock

unread,
Feb 13, 2018, 1:27:25 PM2/13/18
to terrafo...@googlegroups.com
I believe I see the miscommunication here. You were referring to explicitly setting "depends_on" from one module to another, is that correct? 

I was only meaning what I detailed, which is exactly what is mentioned as a workaround in the issue you link:

>Just wanted to mention that while we don't yet support whole-module dependencies, there's nothing stopping you from wiring an output of one module into an input of another, which will effectively draw a dependency between the appropriate resources.


Thanks for the clarification! I hope we're both on the same page of understanding now :)

Cheers,
Clint



On Tue, Feb 13, 2018 at 12:09 PM, ⁞ Fernando Miguel <tl...@fernandomiguel.net> wrote:
 Terraform should absolutely be able to have dependencies on other modules.

--
This mailing list is governed under the HashiCorp Community Guidelines - https://www.hashicorp.com/community-guidelines.html. Behavior in violation of those guidelines may result in your removal from this mailing list.
 
GitHub Issues: https://github.com/hashicorp/terraform/issues
IRC: #terraform-tool on Freenode
---
You received this message because you are subscribed to the Google Groups "Terraform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to terraform-tool+unsubscribe@googlegroups.com.

Javier Ruiz Jiménez

unread,
Feb 13, 2018, 3:25:52 PM2/13/18
to Terraform
Thanks Fernando and Clint:

I was able to solve the issue using the DB Subnet module output as input name for the RDS instance property db_subnet_group_name: 

  db_subnet_group_name    = "${module.aws_rds_sn_pro_01.id}" #"${var.aws_rds_sn_pro_01["name"]}"

Source code and actual plan execution is published in my blog post "Using Terraform to create an AWS VPC with an EC2 Instance and a MariaDB RDS Data Base (I)"

Cheers,
Javier


El martes, 13 de febrero de 2018, 19:27:25 (UTC+1), Clint Shryock escribió:
I believe I see the miscommunication here. You were referring to explicitly setting "depends_on" from one module to another, is that correct? 

I was only meaning what I detailed, which is exactly what is mentioned as a workaround in the issue you link:

>Just wanted to mention that while we don't yet support whole-module dependencies, there's nothing stopping you from wiring an output of one module into an input of another, which will effectively draw a dependency between the appropriate resources.


Thanks for the clarification! I hope we're both on the same page of understanding now :)

Cheers,
Clint


On Tue, Feb 13, 2018 at 12:09 PM, ⁞ Fernando Miguel <tl...@fernandomiguel.net> wrote:
 Terraform should absolutely be able to have dependencies on other modules.

--
This mailing list is governed under the HashiCorp Community Guidelines - https://www.hashicorp.com/community-guidelines.html. Behavior in violation of those guidelines may result in your removal from this mailing list.
 
GitHub Issues: https://github.com/hashicorp/terraform/issues
IRC: #terraform-tool on Freenode
---
You received this message because you are subscribed to the Google Groups "Terraform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to terraform-too...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages