-
Notifications
You must be signed in to change notification settings - Fork 31
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
Add detach support which is compatible with hcl2 used for terraform 0.12 #45
Conversation
input := []byte(` | ||
terraform { | ||
backend "s3" {} | ||
} | ||
|
||
provider "aws" { | ||
region = "us-east-1" | ||
region = "${var.aws_region}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this to explicitly show that this is HCL 1.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Take a look at my comment and see if you feel like addressing it :).
// Regexp to find if any backend configuration exists | ||
backendDefinitionRe := regexp.MustCompile(`(?s)[{\s+]backend\s+"[^"]+"\s*{`) | ||
// Regexp to find simple backend configuration, which doesn't contain '{}' inside | ||
backendBlockRe := regexp.MustCompile(`(?s)(\s*backend\s+"[^"]+"\s*{[^{]*?})`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it be easier to, instead of regex, iterate the input as follows:
ix = in.find("\"backend\"")
bracket_count = 0
for ; ix<len(in); ix++ {
if in[ix]=='{' {
bracket_count++
}
if in[ix]=='}' {
bracket_count--
if bracket_count==0 {
end_ix = ix
break
}
}
}
That way we support complicated configs as well, right? There are some edge cases of course, but this covers a lot more expected cases.
This does assume that the config is correct HCL of course.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I thought about this solution. It actually doesn't look as bad at I thought it would.
It's still not ideal, because '{' or '}' can be part of some other lexeme. But in reality this is very unlikely. I'll change the code to what you've suggested, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I implemented suggested approach and got to writing tests, and I'm not sure if it's a good approach anymore.
The problem is that this config
terraform {
backend "local" {
constant = "weird_string_{"
}
}
Will be recognized as correct expression and turned into
terraform {
I think it's better to fail explicitly in this case.
So once the HCL2 library is ready we should parse config using it, but until then, I'd stick with regexp on simple configs and failures on complex ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments and questions.
// This method should be rewritten once hcl2 supports AST traversal and modification. | ||
func deleteTerraformBackendConfigWithHCL2(in []byte) (updatedConfig []byte, err error) { | ||
// Regexp to find if any backend configuration exists | ||
backendDefinitionRe := regexp.MustCompile(`(?s)[{\s+]backend\s+"[^"]+"\s*{`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do these two regexps need to be different?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a decision to only work with simple cases, where backend configuration doesn't have other braces inside. However, I want to notify the user, that may have a complex configuration about the error (that backend configuration was not removed).
The first regex is to find whether any backend configuration exists, second to find backend configuration that doesn't have braces inside.
Please let me know, if you think I need to put more comments about it in the code.
// Regexp to find if any backend configuration exists | ||
backendDefinitionRe := regexp.MustCompile(`(?s)[{\s+]backend\s+"[^"]+"\s*{`) | ||
// Regexp to find simple backend configuration, which doesn't contain '{}' inside | ||
backendBlockRe := regexp.MustCompile(`(?s)(\s*backend\s+"[^"]+"\s*{[^{]*?})`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be worth expanding this regexp and commenting it, e.g.:
https://stackoverflow.com/questions/24588352/go-idiom-for-writing-long-regular-expressions-embedded-comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack, thanks for the suggestion, I've added comments.
90fa618
to
3144964
Compare
0af9a19
to
310caea
Compare
310caea
to
64bb150
Compare
expected string | ||
}{ | ||
{ | ||
config: ` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still looks weird. Is it because of a tabs/spaces mix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the tab/space issue but after that LGTM! THANK YOU FOR YOUR FANTASTIC WORK!!!
This fixes #44
Context:
--detach
flag is used in astro to make terraform migrations easier. When terraform resources need to be moved or deletedterraform state
subcommands are used to manipulate the state file.If the remote backend is configured, state file will be uploaded after state manipulation is successful. Which is not desired while migration script is being tested. With
detach
option astro inits the module (this downloads the state file from remote), modifies the configuration to remove remote backend (which makes terraform use "local" backend) and runsterraform init -force-copy
again to re-initialize with new backend. See more in https://www.terraform.io/docs/backends/config.html#unconfiguring-a-backend.There were two issues with
--detach
flag that were uncovered by terraform 0.12 upgrade:terraform
block, but didn't containbackend
block. This bug exists with the older versions of terraform. This is fixed by changingastDel
toastDelIfExists
.Terraform 0.12 switched to the new language (HCL2), so old parsing mechanism stopped working.
I wasn't able to find a way to walk and modify tree with https://godoc.org/github.com/hashicorp/hcl2 (similar issue reported https://github.com/hashicorp/hcl2/issues/23), so I'm using regexp to do this for the simple configurations. That unblocks us for the terraform 0.12 upgrade, but may be not a good solution for the long term.