-
Notifications
You must be signed in to change notification settings - Fork 915
fix: Correct secret drift implementation #3069
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
base: main
Are you sure you want to change the base?
Conversation
|
👋 Hi! Thank you for this contribution! Just to let you know, our GitHub SDK team does a round of issue and PR reviews twice a week, every Monday and Friday! We have a process in place for prioritizing and responding to your input. Because you are a part of this community please feel free to comment, add to, or pick up any issues/PRs that are labeled with |
d8a4694 to
4a14a57
Compare
nickfloyd
left a comment
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 really like this approach vs what we have. I just had some thoughts to consider.
| // | ||
| // To solve this, we must unset the values and allow Terraform to decide whether or | ||
| // not this resource should be modified or left as-is (ignore_changes). | ||
| if updatedAt, ok := d.GetOk("updated_at"); ok && updatedAt != secret.UpdatedAt.String() { |
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 belive this will be a breaking change due to ignore_changes - there will be forced recreations now. Not sure if we want a migration path for the users who rely on that or just mark it as a breaking change.
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.
Sorry, I'm not sure I follow how the new code would be breaking? The comment here is incorrect as this will always force new (note this resource doesn't have the destroy_on_drift input to suppress this behaviour).
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.
Just looking into this further and it looks like this resource was relying on a lifecycle block to ignore changes. I've updated the docs to show this correctly being implemented on the new remote_updated_at field. I wouldn't consider a change to how meta arguments work a breaking change.
| ReadContext: resourceGithubActionsEnvironmentSecretRead, | ||
| DeleteContext: resourceGithubActionsEnvironmentSecretDelete, | ||
|
|
||
| CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, m any) error { |
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 really like this approach. Any concerns around external changes to the resource forcing the destruction and recreation of the secret?
For instance...
Let's say a user config has:
resource "github_actions_environment_secret" "api_key" {
...
plaintext_value = "secret-value-123"
lifecycle {
ignore_changes = [plaintext_value]
}
}
- User runs terraform apply
- Other user updates the secret via UI
- User runs terraform apply
The old way the apply would detect no changes. This new approach updated_at and remote_updated_at would be different and therefore force a recreation.
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.
AFAIK setting ignore_changes = [plaintext_value, updated_at, remote_updated_at] should resolve that
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.
IMHO this is a documentation issue, what @deiga added should be the correct solution. If it's not then we'd need to add in the explicit destroy_on_drift field that I'd planned on deprecating.
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.
The correct setting is ignore_changes = [remote_updated_at] and there is now a test to validate this.
| var testAccProviders map[string]*schema.Provider = map[string]*schema.Provider{ | ||
| "github": Provider(), | ||
| } |
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.
AFAIK we should be getting rid of using testAccProviders the recommended approach is to only use ProviderFactories.
Could you mark this as deprecated?
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've made the change to do this already (and stashed them), but I'm holding off adding them in to the PR until the actual changes have been reviewed.
| ReadContext: resourceGithubActionsEnvironmentSecretRead, | ||
| DeleteContext: resourceGithubActionsEnvironmentSecretDelete, | ||
|
|
||
| CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, m any) error { |
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.
suggestion: I think we should be able to forgo adding the remote_updated_at field as we could use customdiff.ForceNewIfChange (https://pkg.go.dev/github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff#ForceNewIfChange) here
Something along the lines of:
CustomizeDiff:
customdiff.ForceNewIfChange(
"updated_at",
func(ctx context.Context, oldValue, newValue, meta any) bool {
remoteUpdatedAt := newValue
if len(remoteUpdatedAt) == 0 {
return false
}
updatedAt := oldValue
if updatedAt != remoteUpdatedAt {
if len(updatedAt) != 0 {
return true
}
}
return false
}
)
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.
Unfortunately you can't do this (I actually coded it up to make sure my mental model was correct). If we're doing drift detection we can't rely on a field updated in the read path as it will never have a change in the pan path. In this case update_at is only updated in read if it's not been able to be calculated as part of the create path, this contrasts with remote_updated_at which is always updated.
| ReadContext: resourceGithubActionsEnvironmentSecretRead, | ||
| DeleteContext: resourceGithubActionsEnvironmentSecretDelete, | ||
|
|
||
| CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, m any) error { |
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.
AFAIK setting ignore_changes = [plaintext_value, updated_at, remote_updated_at] should resolve that
299e8db to
c1c5bc3
Compare
|
I've updated the implementation to not require a recreate now that the diff is being handled correctly. I've also updated the pattern to correctly handle repo identity and support repo renames. |
a770b04 to
d34ded0
Compare
Signed-off-by: Steve Hipwell <[email protected]>
d34ded0 to
12aef66
Compare
Resolves #3049
Before the change?
After the change?
Pull request checklist
Does this introduce a breaking change?
Please see our docs on breaking changes to help!