gruntwork-io / terragrunt

Terragrunt is a flexible orchestration tool that allows Infrastructure as Code written in OpenTofu/Terraform to scale.
https://terragrunt.gruntwork.io/
MIT License
7.98k stars 968 forks source link

backend s3 config: error within if condition - 'encrypt' expected type 'bool', got unconvertible type 'string' #1557

Open cfir-atbay opened 3 years ago

cfir-atbay commented 3 years ago

I'm trying to define a config block for two environments - local and cloud and I'm using the if/else condition but I got an error message for the encrypt attribute of the s3 bucket: 'encrypt' expected type 'bool', got unconvertible type 'string'. If I remove the if/else condition block then it worked but I need to choose between the two environments, so I've to use if/else condition. The config block code:

` config = local.is_local_environment ? {

Local configuration

path = "${path_relative_to_include()}/terraform.tfstate"

} : {

Cloud configuration

bucket = "my-bucket"
key = "terraform/${path_relative_to_include()}/terraform.tfstate"
region = local.region
encrypt = true
dynamodb_table = "terraform-lock"

} } `

brikis98 commented 3 years ago

Could you update your post to use a fenced code block and proper indentation so it's easier to read?

Also, could you share the full log output, including the command you ran?

john-delivuk commented 2 years ago

local backends don't expect any kind of config. Just use null

config = local.is_local_environment ? null : { 
  # Cloud configuration 
  bucket = "my-bucket" 
  key = "terraform/${path_relative_to_include()}/terraform.tfstate" 
  region = local.region 
  encrypt = true 
  dynamodb_table = "terraform-lock" 
} 
}
korenyoni commented 1 year ago

@brikis98 I think you can close this issue, @john-delivuk has provided a solution / workaround.

GergelyKalmar commented 1 year ago

@brikis98 I think the issue still persists. Reproducer:

terragrunt.hcl:

remote_state {
  backend = "s3"
  config = true ? {
    bucket = "terraform-state-test"
    key = "test"
    region = "us-east-1"
    encrypt = true
  } : {}
}

main.tf:

terraform {
  backend "s3" {}
}

Does not look like a Terragrunt issue per se though.

GergelyKalmar commented 1 year ago

It works fine as long as the config map contains the same type of objects.

h3adache commented 1 year ago

Even though terraform ignores path in local configs, it is still a documented parameter

In my case, I'm using it to check that the state key won't collide when doing local plans.

  config = local.is_atlantis ? {
    region         = "us-east-1"
    bucket         = "xxxx"
    dynamodb_table = "xxxx"
    key            = "${local.service_state_key}/terraform.tfstate"
    encrypt        = true
    } : {
    path = "${local.service_state_key}/terraform.tfstate"
  }

It would be nice to add support for this.

h3adache commented 1 year ago

workaround

locals {
  ....
  remote_backend = local.use_local ? "local" : "s3"
  remote_state_config = {
    s3 = {
      region         = "us-east-1"
      bucket         = "xxxxx"
      dynamodb_table = "xxxx"
      key            = "${local.service_state_key}/terraform.tfstate"
      encrypt        = true
    }
    local = {
      path = "${local.service_state_key}/terraform.tfstate"
    }
  } 
}

remote_state {
  backend = local.remote_backend
  config  = local.remote_state_config[local.remote_backend]
  generate = {
    path      = "~backend.tf"
    if_exists = "overwrite_terragrunt"
  }
}
jacekgajek commented 1 month ago

I also encounter this bug. The workaround by @h3adache works for me.