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

GCloud backend #15592

Closed
wants to merge 40 commits into from
Closed

GCloud backend #15592

wants to merge 40 commits into from

Conversation

pbzdyl
Copy link
Contributor

@pbzdyl pbzdyl commented Jul 19, 2017

Hello,

I have implemented a new backend: GCloud. It uses Google Storage for persisting state files and for distributed locks. It supports multiple workspaces.

Thanks to the authors of remote-state/consul and remote-state/s3 as I used their implementation as a basis for my code. Disclaimer: I am new to Go and Terraform, so please forgive me any dumbness in the code!

Features:

  • remote locking
  • multiple workspaces
  • uses account key JSON file (credentials option, either file path to the JSON file or directly JSON contents)
  • if credentials is not specified, uses Google Application Default Credentials

Example configuration:

terraform {
  backend "gcloud" {
    bucket = "my-bucket"
    state_dir = "terraform-state"
    credentials = "path/to/account-key.json"
  }
}

Actual state file URL will be: gs://${bucket}/${state_dir}/${workspace_name}.tfstate
and a lock file will be created at: gc://${bucket}/${state_dir}/$workspace_name}.tflock

State locks use Google Cloud Storage Concurrency Control mechanism.

I am aware there is already the gcs backend. However, my understanding is that it is a legacy remote client implementation which doesn't support multiple workspaces. There would also be a risk of regressions potentially impacting deployments that use it.

This is of course still work in progress as I am not sure if this PR would be accepted or not. If there is a chance it could be merged, I would complete the PR with tests, documentation updates and anything suggested by the reviewers.

Best regards,
Piotr

@pbzdyl pbzdyl force-pushed the gcloud-backend branch 3 times, most recently from b20b905 to dc15917 Compare July 19, 2017 11:49
@sl1pm4t
Copy link
Contributor

sl1pm4t commented Aug 2, 2017

Hi @pbzdyl
I'm glad my colleague pointed this PR out to me, because I was about to start work on implementing a GCS backend.

I contributed the legacy gcs remote last year, and you're correct that it doesn't support workspaces or locking etc - simply because those concepts didn't exist in Terraform back then.

If this backend is accepted, I don't see any need to keep the existing gcs remote. Just like the legacy s3 remote was removed when the s3 backend was implemented.
EDIT: For this reason, I think this backend should also be renamed to gcs.

I'll give this backend a try - thanks!

@nodesocket
Copy link

👍 for this replacing the existing gcs integration if everything checks out.

@pbzdyl
Copy link
Contributor Author

pbzdyl commented Aug 4, 2017

Hello @sl1pm4t ,

Thanks! Please, do share your feedback from testing this PR. If you have any suggestions for the PR's code, I would be happy to hear too as I am new to terraform and Go so I am sure there is something I could improve.

I am not sure removing the current gcs implementation and replacing it with this one using the same name would be welcomed by users of the current gcs as it would be backward incompatible. By using a different name, users could migrate from one backend to another by changing the configuration and moving their state.

@catsby catsby requested a review from jbardin September 6, 2017 15:51
@octo
Copy link
Contributor

octo commented Sep 7, 2017

Hi @pbzdyl, thank you very much for your work!

I was about to start working on implementing locking for the GCS backend when I stumbled into this PR. I'm quite interested in moving this along; are you still interested in working on this? I'd be happy to collaborate on this; I could e.g. send PRs against your feature branch if that's okay with you …?

Best regards,
—octo

@pbzdyl
Copy link
Contributor Author

pbzdyl commented Sep 7, 2017

Hello @octo,

Yes - definitely. However, I am not sure if this PR will be accepted as there has been no feedback from Terraform team.

What kind of changes would you like to add to this PR?

Regards,
Piotr

@octo
Copy link
Contributor

octo commented Sep 7, 2017

@pbzdyl Great! Mostly coding style changes for now, but there are two noteworthy changes:

  1. Return the GCS object's generation as the lock ID. This allows Unlock() to call "delete if generation matches" immediately, removing one round-trip.
  2. Hold on to the context passed to the configure() callback to avoid calling context.Background().

The changes are in the pr/15592 branch. I'll open a PR against your repo in a minute.

Thanks and best regards,
—octo

@jbardin
Copy link
Member

jbardin commented Sep 7, 2017

Hi,

Sorry about the delayed response here, and thanks for the work you put into this!
I hope to catch up with a review shortly, but I have a preliminary question; Are there some incompatibilities that are preventing updating the existing "gcs" remote state to a backend? We generally would prefer a transparent upgrade path for existing users, rather than creating an entirely new backend.

@pbzdyl
Copy link
Contributor Author

pbzdyl commented Sep 7, 2017

Hello @jbardin,

Do you mean removing current gcs implementation and renaming the new backend to gcs? I am not sure I have enough knowledge about the internals but I will try to implement it this way and test it locally.

@octo
Copy link
Contributor

octo commented Sep 7, 2017

Hi @jbardin,

This PR adds support for named states, which are stored under a configurable directory. Previously, the gcs backend was using a state file.

I think it should be possible to add backwards compatibility and rename this package to "gcs" so it can serve as a drop-in replacement. Do you know if another backend has implemented something similar so we can go for consistent behavior?

Best regards,
—octo

@jbardin
Copy link
Member

jbardin commented Sep 7, 2017

Hi @octo,

I think the existing "remote-state" backends were all migrated from legacy remote state implementations, with azure being the most recent. S3 might be a good learning example, as it probably has the most "hacks" for legacy behavior, and is one of the more complex requiring S3 and DynamoDB in concert.

@octo
Copy link
Contributor

octo commented Sep 7, 2017

Great, thanks @jbardin!

@octo
Copy link
Contributor

octo commented Sep 11, 2017

Hi everybody!

pbzdyl#2 has a lot of updates to this PR and should appear here once merged by @pbzdyl.

How do you want to deal with the merge conflicts in vendor/? Should I rebase onto or merge the master branch? I can also remove the commit that changes vendor/ and we can do this as the last commit of the PR.

Best regards,
—octo

@octo
Copy link
Contributor

octo commented Sep 11, 2017

Thank you @pbzdyl!

@jbardin I've done all the changes I was intending to make; from my POV, this is good to go. If anything's missing, please let me know and I'll make sure to add / change that.

Best regards,
—octo

@jbardin
Copy link
Member

jbardin commented Sep 11, 2017

Hi @octo,

Thanks for the update, I'll take a look ASAP.
As for the conflicts, we usually prefer to rebase on master then force push the new commits into the PR. The vendor files however are a little different, since you can't "resolve" conflicts in there. I would drop the first commit, rebase on master, then use govendor to update the missing dependencies.

Don't worry if you can't get the vendor files to work out. If it turns into too much of a mess, I can transfer this whole PR into a branch here and fix them at the end.

@pbzdyl pbzdyl force-pushed the gcloud-backend branch 2 times, most recently from 73cd4d7 to 4b7fd11 Compare September 11, 2017 20:15
@pbzdyl
Copy link
Contributor Author

pbzdyl commented Sep 11, 2017

I have removed the commit updating vendor files and rebased on the latest master branch to resolve merge conflicts. I will try to update vendor files tomorrow.

@pbzdyl pbzdyl force-pushed the gcloud-backend branch 2 times, most recently from 8dd7c42 to 64ad7d5 Compare September 11, 2017 21:20
@pbzdyl
Copy link
Contributor Author

pbzdyl commented Sep 11, 2017

@jbardin, I was able to update vendor files.

@pbzdyl
Copy link
Contributor Author

pbzdyl commented Sep 12, 2017

I was testing the new backend today and I noticed that we probably should add (ignored) project configuration property to make the new backend fully compatible with the old one so that users with existing gcs configuration can start using the new one without any configuration changes.

@jbardin, @octo What would be the preferred way of handling it? Shall it be marked with Deprecated or Removed?

Similarly, should path be flagged with Deprecated?

@octo
Copy link
Contributor

octo commented Sep 12, 2017

I just tried the new code for the first time, and there are some small issues that need fixing:

  • The old code had a project option which the new code is missing. I'll have to find out what it was used for and do something sensible.
  • The credentials option is evaluated relative to the process's working directory, not the terraform working directory which is unexpected. I.e. if example.tf references creds.json, this should be interpreted as relative to example.tf, not the (meaningless) directory from which terraform init /path/to/terraform/wd was executed.
  • We should make an effort to create the bucket for the user if it doesn't exist. This is a UX issue that only pops up when initializing, but I think is worth fixing in code to give new users an easier time getting started.

I'll send patches for those issues soon. If you know a way to determine the terraform working directory (without having access to command.Meta.DataDir(), I assume) I'd love to hear it :)

Best regards,
—octo

octo added 13 commits October 5, 2017 10:48
This resurrects the previously documented but unused "project" option.
This option is required to create buckets (so they are associated with the
right cloud project) but not to access the buckets later on (because their
names are globally unique).
…ent variable.

This copies behavior from the Google Cloud provider.
This allows to select the region in which a bucket is created.
This copies behavior from the Google Cloud provider.
This calls backend.TestBackend() and remote.TestRemoteLocks() for
standardized acceptance tests. It removes custom listing tests since
those are performed by backend.TestBackend(), too.

Since each tests uses its own bucket, all tests can be run in parallel.
Enabling versioning without setting up lifecycle management leads to
every lock file being archived, slowly accruing useless data.
This way tests clean up after themselves and don't leak buckets.
…ting.

Since bucket names must be *globally* unique. By including the project
ID in the bucket name we ensure that people don't step on each other's
feet when testing.
@jbardin
Copy link
Member

jbardin commented Oct 5, 2017

@octo: Everything looks good to me, thanks for hanging in there!

I'm going to hold off merging briefly, just until I can get some hands on testing with existing gcs remote states to try and catch any regressions. I do want to get that done ASAP though, so we don't start to lag behind and run into more merge conflicts, and can get this in before we start the process for the next major release.

@octo
Copy link
Contributor

octo commented Oct 5, 2017

@jbardin Awesome, thank you! :)

@octo
Copy link
Contributor

octo commented Oct 17, 2017

Hi @jbardin, is there any update? Is there anything I can help with to move this forward?

Best regards,
—octo

@jbardin
Copy link
Member

jbardin commented Oct 20, 2017

@octo: Thanks, just trying to schedule time to QA a build with this. It needs to be in before the beta process for 0.11 ;)

@jbardin jbardin mentioned this pull request Oct 27, 2017
@jbardin
Copy link
Member

jbardin commented Oct 27, 2017

moved this over to a branch where I could resolve the merge conflict asap.

@jbardin jbardin closed this Oct 27, 2017
@octo
Copy link
Contributor

octo commented Oct 28, 2017

🎉 Thanks @pbzdyl and @jbardin!

@pbzdyl
Copy link
Contributor Author

pbzdyl commented Oct 28, 2017

Thank you @octo - all the hard work was done by you!

@pbzdyl pbzdyl deleted the gcloud-backend branch October 28, 2017 07:03
@sl1pm4t
Copy link
Contributor

sl1pm4t commented Oct 28, 2017

Thanks @pbzdyl + @octo + @jbardin and all who helped with this one!

@ghost
Copy link

ghost commented Nov 24, 2017

All,

Can someone check the following bug that seems to be related to be this PR?

#16741

@negz negz mentioned this pull request Dec 4, 2017
@ghost
Copy link

ghost commented Apr 6, 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 6, 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.

7 participants