João Amaro
João Amaro

Reputation: 496

Why is terraform saying that my object has no attributes?

I'm using terraform 0.12.31 and trying to create some AWS SES resources. There's one which is returning an error message:

    aws_ses_domain_identity.ses_domain_per_tenant is object with no attributes
    each.key is "a.env.account.info"

    aws_ses_domain_identity.ses_domain_per_tenant is object with no attributes
    each.key is "b.env.account.info"
    
    aws_ses_domain_identity.ses_domain_per_tenant is object with no attributes
    each.key is "c.env.account.info"

This is my code:

resource "aws_ses_domain_identity" "ses_domain_per_tenant" {
  for_each  = toset(var.enable_per_tenant_email_domain ? var.tenants_email_domain : [])
  domain    = each.key
}

resource "aws_ses_domain_dkim" "dkim_domain_per_tenant" {
  for_each  = toset(var.enable_per_tenant_email_domain ? var.tenants_email_domain : [])
  domain    = aws_ses_domain_identity.ses_domain_per_tenant[each.key].domain
}

I also have this resource as part of the same code, which is working fine:

resource "aws_route53_record" "ses_amazonses_verification_record_per_tenant" {
  for_each  = toset(var.enable_per_tenant_email_domain ? var.tenants_email_domain : [])
  records   = [aws_ses_domain_identity.ses_domain_per_tenant[each.key].verification_token]
}

Where:

tenants_email_domain = ['a.env.account.info', 'b.env.account.info', 'c.env.account.info']

What's happening here?

Upvotes: 0

Views: 2220

Answers (2)

Marko E
Marko E

Reputation: 18203

Except for having the way you are currently using for_each meta-argument, there is an additional thing you can do which can also help avoiding some of the errors and duplicating code and that is chaining for_each between resources [1]:

resource "aws_ses_domain_identity" "ses_domain_per_tenant" {
  for_each = toset(var.enable_per_tenant_email_domain ? var.tenants_email_domain : [])
  domain   = each.key
}

resource "aws_ses_domain_dkim" "dkim_domain_per_tenant" {
  for_each = aws_ses_domain_identity.ses_domain_per_tenant
  domain   = each.value.domain
}

Of course, in order for this to work, the values assigned to the tenants_email_domain have to be fixed to be strings:

tenants_email_domain = ["a.env.account.info", "b.env.account.info", "c.env.account.info"]

[1] https://developer.hashicorp.com/terraform/language/meta-arguments/for_each#chaining-for_each-between-resources

Upvotes: 1

ishuar
ishuar

Reputation: 1328

As suggested in the comments the issue is because of the variable tenants_email_domain value having single quotes '.

On the terraform string documentation also they only mention string literals only with ".

The following code generates a valid plan.


resource "aws_ses_domain_identity" "ses_domain_per_tenant" {
  for_each = toset(var.enable_per_tenant_email_domain ? var.tenants_email_domain : [])
  domain   = each.key
}

resource "aws_ses_domain_dkim" "dkim_domain_per_tenant" {
  for_each = toset(var.enable_per_tenant_email_domain ? var.tenants_email_domain : [])
  domain   = aws_ses_domain_identity.ses_domain_per_tenant[each.key].domain
}

variable "tenants_email_domain" {
  type = list(string)
  default = ["a.env.account.info", "b.env.account.info", "c.env.account.info"] ## updated ` with "" ##
}
variable "enable_per_tenant_email_domain" {
  type = bool
  default = true
}

Upvotes: 0

Related Questions