-
Notifications
You must be signed in to change notification settings - Fork 9.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Data resource in a module is not delayed #23242
Comments
Hi @josh-barker! Thanks for reporting this. From looking through your configuration and the output you've shared, it looks like this is happening because The pattern of reading something using a data resource in the same configuration where it's created does tend to lead to this sort of problem, and so we'd recommend avoiding that where possible. In this case, it looks like it could be avoided by passing the resource group as a whole between modules, rather than having one module write it to the API and another module then read it back. The required data is already in Terraform, so we can pass it around in a module composition style rather than having the module "rg_2" {
source = "./terraform-azurerm-resource-group"
name = "rg-2"
location = "australiasoutheast"
}
module "rsv" {
source = "./terraform-azurerm-rsv"
resource_group = module.rg_2.resource_group
} Inside the variable "resource_group" {
type = object({
# Only need to include the subset of attributes that the module
# actually relies on. An object type constraint accepts any object
# that has _at least_ the given attributes, ignoring any extras.
name = string
location = string
})
} You can then, for example, access the resource group location in the module as # If we put the data resource in the caller rather than in the child module
# then the module doesn't need to be aware of whether this is an object
# managed in this configuration or whether it's managed elsewhere.
data "azurerm_resource_group" "example" {
name = "rg-2"
}
module "rsv" {
source = "./terraform-azurerm-rsv"
# The data resource's object type also matches the variable
# type constraint, so we can pass it directly here.
resource_group = data.azurerm_resource_group.example
} With that said, Terraform is behaving as designed in the situation you described here, but we can see that Terraform is not giving good feedback on what the problem might be and what changes you might make to solve it. We're going to relabel this as an enhancement to represent exploration either of giving better feedback in this situation or potentially introducing a feature to make this situation more convenient to express in configuration. We're not sure at the moment what form that might take, but we want to retain the record of the use-case for future discussion and design work. Thanks again for reporting this! Hopefully the above is helpful guidance for expressing your intent within the current design of the Terraform language. |
Thanks for the detailed explanation @teamterraform The key thing that is confusing is when we deploy scenario 2 and everything works, compared with an additive deployment in scenario 1. |
Hi @teamterraform , I have a similar issue using an Specifically, if an If I use a single configuration file with the following contents, changing the provider "aws" {
region = "us-east-1"
}
variable "random_length" {
type = number
description = "The number of random characters to use in the name"
default = 4
}
resource "random_string" "suffix" {
length = var.random_length
upper = false
special = false
}
data "aws_caller_identity" "current" {}
data "aws_iam_policy_document" "roleA-policy" {
statement {
actions = [
"sts:AssumeRole",
]
effect = "Allow"
resources = [aws_iam_role.roleA.arn]
}
}
data "aws_iam_policy_document" "roleA-arp" {
statement {
actions = [
"sts:AssumeRole",
]
effect = "Allow"
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/Staff"
]
}
}
}
resource "aws_iam_role" "roleA" {
name = "RoleA-${random_string.suffix.result}"
assume_role_policy = data.aws_iam_policy_document.roleA-arp.json
}
resource "aws_iam_role_policy" "roleA" {
name = "RoleA-AssumeRole"
role = aws_iam_role.roleA.id
policy = data.aws_iam_policy_document.roleA-policy.json
}
data "aws_iam_policy_document" "roleB-policy" {
statement {
actions = [
"sts:AssumeRole",
]
effect = "Allow"
resources = [aws_iam_role.roleA.arn]
}
}
data "aws_iam_policy_document" "roleB-arp" {
statement {
actions = [
"sts:AssumeRole",
]
effect = "Allow"
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/Staff"
]
}
}
}
resource "aws_iam_role" "roleB" {
name = "RoleB"
assume_role_policy = data.aws_iam_policy_document.roleB-arp.json
}
resource "aws_iam_role_policy" "roleB" {
name = "RoleB-AssumeRole"
role = aws_iam_role.roleB.id
policy = data.aws_iam_policy_document.roleB-policy.json
} However, if I move
provider "aws" {
region = "us-east-1"
}
variable "random_length" {
type = number
description = "The number of random characters to use in the name"
default = 4
}
resource "random_string" "suffix" {
length = var.random_length
upper = false
special = false
}
data "aws_caller_identity" "current" {}
data "aws_iam_policy_document" "roleA-policy" {
statement {
actions = [
"sts:AssumeRole",
]
effect = "Allow"
resources = [aws_iam_role.roleA.arn]
}
}
data "aws_iam_policy_document" "roleA-arp" {
statement {
actions = [
"sts:AssumeRole",
]
effect = "Allow"
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/Staff"
]
}
}
}
resource "aws_iam_role" "roleA" {
name = "RoleA-${random_string.suffix.result}"
assume_role_policy = data.aws_iam_policy_document.roleA-arp.json
}
resource "aws_iam_role_policy" "roleA" {
name = "RoleA-AssumeRole"
role = aws_iam_role.roleA.id
policy = data.aws_iam_policy_document.roleA-policy.json
}
output "role" {
value = aws_iam_role.roleA
}
provider "aws" {
region = "us-east-1"
}
module "ext-role" {
source = "../roleA"
random_length = 3
}
data "aws_caller_identity" "current" {}
data "aws_iam_policy_document" "roleB-policy" {
statement {
actions = [
"sts:AssumeRole",
]
effect = "Allow"
resources = [module.ext-role.role.arn]
}
}
data "aws_iam_policy_document" "roleB-arp" {
statement {
actions = [
"sts:AssumeRole",
]
effect = "Allow"
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/Staff"
]
}
}
}
resource "aws_iam_role" "roleB" {
name = "RoleB"
assume_role_policy = data.aws_iam_policy_document.roleB-arp.json
}
resource "aws_iam_role_policy" "roleB" {
name = "RoleB-AssumeRole"
role = aws_iam_role.roleB.id
policy = data.aws_iam_policy_document.roleB-policy.json
} The first apply will report |
Is this the same issue as this? |
This appears to be a variation of #25961, which is closed by #26284 and will be included in the 0.14 release. The caveat here is that implicitly delaying data source updates even when the configuration is known will be limited to direct references to other resource. This can be worked around now with The new data lifecycle changes here should work to make the behavior easier to understand, and provide adequate flexibility when data sources depend on manages resource.
Thanks! |
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further. |
Terraform Version
Terraform Configuration Files
Part 1
Part 2
Note: The modules I'm using are internal and not publicly available.
Expected Behavior
I expect that the plan/apply will succeed and create the resource group and RSV.
Actual Behavior
Steps to Reproduce
terraform init
terraform apply
terraform apply
=> Error
Another scenario - All code written for first deploy
However, if I have all the code with no state stored yet, it behaves as I expect.
The text was updated successfully, but these errors were encountered: