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

Add App Engine Application support #1503

Merged
merged 5 commits into from
May 19, 2018
Merged

Add App Engine Application support #1503

merged 5 commits into from
May 19, 2018

Conversation

paddycarver
Copy link
Contributor

This PR adds an app_engine block to the google_project resource. Adding the block creates an App Engine app associated with the project. App Engine apps cannot be deleted without deleting the project, so we tie the app's lifecycle to the project's. Removing the app_engine block from a config should force a project to be recreated, as there's no way to delete or disable it.

For whatever reason, we're currently getting a bunch of errors any time we try to update an App Engine app through the API, so every change forces a new resource. This is sub-optimal, as projects can't reuse their IDs, which makes recreating them problematic. This can still be accomplished using the random provider, but isn't very nice. I'll be pursuing better support there, but we need some upstream support on that. I'll follow up on the relevant issues.

The serving_status field is also less useful than it could be, as changing it will force new because of our problems updating. I figure it can at least be read now, and can be set at create, so I included it; when we get the update problems resolved, we can do some more with it, I think.

This should have all the code, but who really knows if it works or not,
tbh.
Add a test case that exercises the obvious path, and fix the some of the
bugs it exposed.
IAP has no reasonable support policy, because PATCH is broken, and IAP
must be configured with an OAuth2 client ID and secret that belongs to
the project the app is associated with. There's no programmatic way to
create Clients. But we create the project and the app at the same time,
and we can't update because PATCH is broken. So this just drops IAP. It
also forces all our updates to ForceNew, because we can't update.

Also, adds more test coverage and docs, and fixes import by not relying
on the config for setting app engine info in state.
)

var (
appEngineOperationIdRE = regexp.MustCompile(fmt.Sprintf("apps/%s/operations/(.*)", ProjectRegex))
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm sorry this is such a nit to pick, but IdRE bugs me - can it be IdRegex or IdRegEx or IDReg or IdReg or something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It can be! I'll push an update for you to approve momentarily.

"serving_status": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

I remember why this is set this way, and why that's not desirable, but if you could add a comment explaining, that would probably be best.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Absolutely. I'll also look into just enabling update, because the issues I had with it seem to be gone now that I'm trying to reproduce them o.O

if err != nil {
return err
}
log.Printf("[DEBUG] Creating App Engine if %v is true", app != nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

This one might be a little chatty - since we already have "Enabling App Engine", the lack of that tells us everything that this statement tells us.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, sorry! This was a debug message from when I was figuring out errors. I'll remove it.

@paddycarver
Copy link
Contributor Author

Did the last commit fix the suggestions, @ndmckinley?

@paddycarver paddycarver merged commit cd7364d into master May 19, 2018
if app != nil {
log.Printf("[DEBUG] Enabling App Engine")
// enable the app engine APIs so we can create stuff
if err = enableService("appengine.googleapis.com", project.ProjectId, config); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Won't this mess with people using google_project_services?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a similar approach taken as for disabling the default network, and is documented similarly. I don't know that there's an alternative unless we don't allow people to create App Engine apps in the same apply they create projects :/

Copy link
Contributor

Choose a reason for hiding this comment

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

But wouldn't they already need to enable the resourcemanager api in order to create the project? Couldn't they do that at the same time as the app engine api?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

APIs get enabled on a per-project basis. The project doesn't exist before the project resource's Create function is called, so we can't enable APIs on it beforehand. But by the time the project's Create function is finished, we need the App Engine Admin API enabled, because we're using it. This is the same rationale, I believe, for enabling the compute API when deleting the default network.

The workaround here, if they want to use google_project_services, is to just add the App Engine Admin API to the google_project_services resource, which should (I believe) leave things alone if the API is already enabled.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ohhh that makes sense. Thanks!

@morgante
Copy link

I'm personally not a big fan of embedding this inside the project creation block. For many organizations, projects are centrally created/managed in their own repo while the actual development teams manage what happens inside of them, including app engine.

Could we consider separating this into its own resource, like how we have project services separately?

@paultyng
Copy link

paultyng commented May 21, 2018

@morgante my understanding is that the implementation you described was attempted, but due to limitations in how destroy would work on an app engine application, you have to destroy the project to destroy the application in the API unfortunately, so for now its coupled so the terraform lifecycle will work properly.

App Engine apps cannot be deleted without deleting the project, so we tie the app's lifecycle to the project's.

That being said, I believe this issue is being raised with Google to see if we can figure out some other way of addressing it.

@paddycarver
Copy link
Contributor Author

Hi @morgante! In this case, I feel like there's a strong case for considering App Engine apps and Google Cloud projects to be the same resource:

  1. You can only create an App Engine app, you can't delete it, which feels more to me like upgrading the capabilities of a project than adding a resource.
  2. You can only have one App Engine app per project.
  3. The App Engine app needs to share an ID with the project.

Both 1 and 2 of those are not currently possible with Terraform in an elegant way. If we were to make this a separate resource, Terraform would happily report it was deleted when it was, in fact, not, and we have no way of indicating otherwise, except a line in a log that users would mostly never see. And if the user added multiple google_app_engine_app resources to their project, we'd have no way of indicating that's incorrect; they'd just hit an API error, which is less than ideal.

Because of those reasons, I thought adding it as a sub-block within google_project was the more elegant solution, because what Terraform reports to the user is always accurate, and there are no caveats. If you need to delete your project to do what you're trying to do, Terraform will tell you that.

I do want to make the distinction that this is only for configuring the top-level settings of the App. Further App Engine resources are planned to manage things like versions, services, domain mappings, etc. that will all live as separate resources (or, at least, that's the plan at the moment, pending any implementation troubles). Keep in mind that this resource only allows the configuration of:

  • The domain users of the application authenticate with.
  • The location of the application.
  • The serving status of the application.
  • Whether the application uses health checks or a combination of liveness and readiness checks

I'm also in the process of gathering up the information I obtained implementing this to file an issue with the App Engine team, which will hopefully allow us to offer a google_app_engine_app in the future, as well, but I can't make any promises that will happen, or that it will happen in the immediate future.

@morgante
Copy link

morgante commented May 23, 2018

Hi @paddycarver, I missed the part that there's no way to delete the app without deleting the project - in that case, it makes sense to couple their lifecycles.

Once you have the information or issue, please do ping me - I can help chase internally.

@stevewolter
Copy link

The rollout of this feature is rather disrupting for existing GAE users: If you have existing TF-managed projects that predate this change (don't have an app_engine block) and have GAE enabled, TF will try to delete the project and recreate it w/o GAE. Is this expected? For our team, this would have meant a bunch of accidentally deleted projects if we hadn't enabled the prevent_destroy option.

@danawillow
Copy link
Contributor

@stevewolter I filed a bug on your behalf: #1561

@stevewolter
Copy link

@danawillow Thanks!

chrisst pushed a commit to chrisst/terraform-provider-google that referenced this pull request Nov 9, 2018
…engine_app

Add App Engine Application support
@ghost
Copy link

ghost commented Nov 18, 2018

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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

@ghost ghost locked and limited conversation to collaborators Nov 18, 2018
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.

6 participants