Skip to content
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

helper/schema: Allow identification of a new resource in update func #4446

Merged
merged 1 commit into from
Feb 29, 2016

Conversation

radeksimko
Copy link
Member

TL;DR

This is to avoid situations where we call Update function right from the Create function and the Update function has in some situations no way to differentiate between a new resource and resource that's being updated.

e.g. in KMS I'm enabling/disabling keys in the Update function, but I don't want to call the enable/disable key API at all if I know that the key is enabled by default once created.

Why not ____

d.HasChange ?

You could say that d.HasChange() may cover such situations, but if we have

            "is_enabled": &schema.Schema{
                Type:     schema.TypeBool,
                Optional: true,
                Default:  true,
            },

and is_enabled not present in the HCL template then

d.HasChange("is_enabled")

is always true when creating a new resource. d.GetChange reports false => true which makes it impossible to differentiate between creation & real update from is_enabled=false to is_enabled=true.

Strict separation between Create & Update?

Also you could say that we just may not call Update from Create and make these strictly separated, but that may (in some cases) involve a lot of duplication purely because some attributes can only be set from Update APIs. This approach would therefore make the code much more verbose.

Just always call update?

Because more API calls cost more time - in case like KMS, where we need to confirm the state has been properly propagated it makes a huge difference - even minutes. Each API call also counts toward the limit and we should make Terraform efficient enough to not throttle any APIs.


func (d *ResourceData) IsNewResource() bool {
return d.isNew
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason to not just have IsNewResource() check Id() == "" directly rather than keeping the boolean struct member?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is a good point. Making IsNewResource() just an "alias" for Id() == "" is much cleaner approach. I will update the PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact it doesn't seem to be equivalent, tests are failing.

It's been over a week since I last had my head in this part of codebase, so I don't quite know why, but I'll find out and post an explanation here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is because if we have func Create() { return Update() }

then the Create func already sets id for the resource which means that Id() == "" in Update() function will never be true.

Resources with ForceNew: true are also covered:
https://github.com/TimeIncOSS/terraform/blob/f-schema-new-resource/helper/schema/resource.go#L119-L127


Looking at the code also makes me wonder why do we explicitly call d.SetId("") in most Delete() functions in resources, if we're resetting it here anyway. It seems superfluous.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhh sure that makes sense. This implementation works then.

@phinze
Copy link
Contributor

phinze commented Jan 6, 2016

This seems reasonable at first pass - question on the implementation details, but thanks for the solid explanation!

@radeksimko
Copy link
Member Author

@phinze Let me know if you're happy with the explanation. It also doesn't seem very elegant to me to use that extra struct member, but I can't think of any better solution.

@phinze
Copy link
Contributor

phinze commented Jan 6, 2016

Yep that makes sense - thanks for digging in.

Let me think about this one a bit more. I'm still wondering if the "Create calls Update calls Read" pattern is worth defending with extra code here rather than eating the verbosity of the "Strict separation" route you mentioned.

@josephholsten
Copy link
Contributor

@phinze is this waiting on anything? looks ready-to-go and worth-having.

@phinze
Copy link
Contributor

phinze commented Feb 29, 2016

Just took a second look here - this LGTM @radeksimko.

@phinze phinze removed the thinking label Feb 29, 2016
radeksimko added a commit that referenced this pull request Feb 29, 2016
helper/schema: Allow identification of a new resource in update func
@radeksimko radeksimko merged commit 8bdd921 into hashicorp:master Feb 29, 2016
@radeksimko radeksimko deleted the f-schema-new-resource branch February 29, 2016 20:07
@ghost
Copy link

ghost commented Apr 27, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants