terraform-provider-heroku
                                
                                 terraform-provider-heroku copied to clipboard
                                
                                    terraform-provider-heroku copied to clipboard
                            
                            
                            
                        Newly added `config_vars` should show a realistic diff if they already exist
Currently config_vars don't show an accurate diff until after the first terraform apply has run with those config_vars set.  This makes it very tedious to import apps with lots of config_vars into terraform since you have to manually inspect to make sure you're not accidentally changing things on your first apply run.
The same applies to sensitive_config_vars, mainly in that they shouldn't show a diff (by diff I mean mention that it's changing something when it's not since it doesn't show the actual diff) if there isn't a change when you're adding them.
Terraform Version
Terraform v0.12.20
Heroku Provider Version
+ provider.heroku v2.1.2
Affected Resource(s)
- heroku_app
Terraform Configuration Files
resource "heroku_app" "app" {
  name   = var.app_name
  region = data.heroku_space.default.region
  space  = data.heroku_space.default.name
  acm    = false
  internal_routing = var.internal_routing
  organization {
    locked = false
    name = var.heroku_team_name
    personal = false
  }
  config_vars = [
    EXISTING_CONFIG_VAR = "Hopefully the same value but you can't tell"
  ]
}
Expected Behavior
When I run terraform plan I expect it to show no changes since the EXISTING_CONFIG_VAR I'm setting is the same as is already in the all_config_vars value in the state file.
Actual Behavior
It shows that there's going to be a change
  # module.my_module_app_name.heroku_app.app will be updated in-place
  ~ resource "heroku_app" "app" {
...
      ~ config_vars           = {
          + "EXISTING_CONFIG_VAR"            = "Hopefully the same value but you can't tell"
        }
...
Plan: 0 to add, 1 to change, 0 to destroy.
Steps to Reproduce
- terraform planor- terraform applywith a newly added config var in your- tffiles that already exists in the actual heroku app
Just to confirm, is your workflow the following:
- Import a heroku_appresource with eitherconfig_vars&sensitive_config_vars.
- Execute a terraform plan|apply, which shows aplandiff that terraform wants to create those vars again?
If so, does your state file have config_vars & sensitive_config_vars properly set post import?
Correct on the workflow
And yes, the state file does not have config_vars and sensitive_config_vars set correctly post import
I've found 2 super hacky ways of getting a decent diff
1
- terraform state pull > state.json
- increment the serialvalue instate.json
- Manually edit state.jsonwith the proper keys forconfig_varswith any values so that it'll recognize a diff on nextplan. Note it populates theconfig_varsvalues correctly on the nextplanrun once the right keys are in theconfig_varssection of the state, so it'll show the proper diff no matter what I put in the values when I manually modify the state file.
- terraform state push state.json
- terraform plannow shows a diff if I change things, or no diff if I matched the existing value, instead of showing it's creating the- config_var
2
- make buildthis commit https://github.com/mmrobins/terraform-provider-heroku/commit/f408db6b39f9b6c43fe14b423b6262272d86c1bb
- copy provider in for local use per the README https://github.com/terraform-providers/terraform-provider-heroku/blob/master/README.md#using-the-provider
- terraform plannow shows a diff of all config vars
Method 1 I've tried running terraform apply after checking out the diff, and it's fine.  Method 2 I haven't run terraform apply after doing the diff because I don't really understand my hacky code modification enough to predict what will happen.
Gotcha. That's no good if the import on heroku_app isn't probably setting config_vars and sensitive_config_vars. This is why you're seeing a diff when you plan or apply. Luckily, Heroku API essentially will do nothing if you trying to add a config var that's already set on the target app.
https://github.com/mmrobins/terraform-provider-heroku/commit/f408db6b39f9b6c43fe14b423b6262272d86c1bb would set all of a config vars under heroku_app.config_vars. This would include any variables a user defined in heroku_app.sensitive_config_vars, thereby rendering sensitive_config_vars ineffective in preventing any 'sensitive' config vars like SOME_PRIVATE_API_TOKEN from being plaintexted in a CI system.
For background, Heroku doesn't differentiate between sensitive and non-sensitive config vars. We added this difference into the provider so that users have a bit more flexibility in managing their config vars in a CI system. Marking heroku_app.config_vars sensitive when the provider didn't have heroku_app.sensitive_config_vars would have masked every config vars during a plan|apply, which could hamper other users from determining if say RAILS_ENV will be the desired value.
Let me take a look at why the import isn't working properly for this resource. Once that is solved, your workflow shouldn't have any further issues.
I would really like to see this work too 👍I wonder if the tricky part will be making it work smoothly with heroku_app_config_association etc.
Note that config vars set by attached Heroku Addons should be ignored from Terraform state. They change dynamically (such as periodic Postgres credential rotation). IMO Inverting the ownership of their state to Terraform will confuse things.
While I believe that App import can be fixed to capture existing config variables, it will probably be a bit complicated to filter out Addons.
Yeah agreed that would really confuse things.
Could we make it work so that the import only pulls in config vars that are defined in the terraform config, and ignores the rest?
Could we make it work so that the
importonly pulls in config vars that are defined in the terraform config, and ignores the rest?
Yep, that was the original intent.
I would really like to see this work too 👍I wonder if the tricky part will be making it work smoothly with
heroku_app_config_associationetc.
@bensymonds Is your statement above saying you're trying to manage the same config vars using heroku_app.config_vars and heroku_app_config_association.config_vars?
@davidji99 No. I was just thinking given there are two ways to specify config vars (directly in the heroku_app resource, or via a heroku_app_config_association resource) it might complicate things. I didn't think about it any further than that - it might not be complicated at all.
@davidji99 No. I was just thinking given there are two ways to specify config vars (directly in the
heroku_appresource, or via aheroku_app_config_associationresource) it might complicate things. I didn't think about it any further than that - it might not be complicated at all.
Ah gotcha. It won't be complicated so long as one doesn't manage the same config vars on both resources. Otherwise, you'll get an infinite plan loop.
For heroku_app.config_vars & heroku_app.sensitive_config_vars, the provider compares what the user has defined in both attributes with all of the config vars returned by the API to make sure each attribute's values exist remotely before setting them in state. Since the Heroku Platform API has no distinction of config var sensitivity, we need to do this comparison before setting these attributes in state.
However during a terraform resource importation, the provider SDK does not have access to the resource's schema so the comparison does not work and nothing is set in state. I've reached out to Hashicorp to see if there is a solution.
FYI, what I described above is why heroku_app_config_association does not allow imports.