-
Notifications
You must be signed in to change notification settings - Fork 9.7k
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
providers/google: Create and delete Service Accounts #9946
providers/google: Create and delete Service Accounts #9946
Conversation
Ping @danawillow for super-early initial review. Tomorrow I'll add docs and support for IAM policy attachment. |
This is awesome! I actually went looking to see if Terraform could do this just the other day. |
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.
Looks fine overall, just a few small things.
sa, err := config.clientIAM.Projects.ServiceAccounts.Get(d.Id()).Do() | ||
if err != nil { | ||
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { | ||
log.Printf("[WARN] Removing service account %q because it no longer exists", d.Id()) |
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 feel like if I saw this error message when running a command I would have no idea what it meant. Maybe something like "resetting reference to" instead of "removing"? Not sure I love that either honestly. What exactly is happening here?
return fmt.Errorf("Error getting service account with name %q: %s", d.Id(), err) | ||
} | ||
|
||
return fmt.Errorf("Error reading service account: %q", err) |
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 does the above error message reference the name and not this one?
var testAccGoogleServiceAccount_basic = ` | ||
resource "google_service_account" "acceptance" { | ||
account_id = "%v" | ||
display_name = "%v" |
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.
nit: alignment
|
||
var testAccGoogleServiceAccount_basic = ` | ||
resource "google_service_account" "acceptance" { | ||
account_id = "%v" |
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.
Instead of passing static variables, would it not be preferable to have a test that passes a random character string, similar to the other google provider tests (example:
terraform/builtin/providers/google/resource_compute_route_test.go
Lines 104 to 110 in 45f441f
resource "google_compute_route" "foobar" { | |
name = "route-test-%s" | |
dest_range = "15.0.0.0/24" | |
network = "${google_compute_network.foobar.name}" | |
next_hop_ip = "10.0.1.5" | |
priority = 100 | |
}`, acctest.RandString(10), acctest.RandString(10)) |
This would ensure a test wouldn't falsely pass because a resource wasn't cleaned up matching the static name. Or is there some reason I'm missing that wouldn't work for this resource type?
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 initially had some concerns about a circular reference between service accounts and IAM policies. Still working through that, but I'll use the random char where possible. Thanks!
3f260aa
to
5423349
Compare
@cblecker You want to make the call on merging this? Makes sense to me as you're interested in the feature :) |
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.
As far as I can see, the code looks good. Do the acceptance tests all pass? I'm still in the learning stages of Go, though. A few alignment and spacing nits.
I'll let someone else make the call on merging though, both because I'm inexperienced, and I don't have merge rights :P
@@ -24,6 +24,9 @@ | |||
<ul class="nav nav-visible"> | |||
<li<%= sidebar_current("docs-google-project") %>> | |||
<a href="/docs/providers/google/r/google_project.html">google_project</a> | |||
</li> | |||
<li<%= sidebar_current("docs-google-service-account") %>> | |||
<a href="/docs/providers/google/r/google_service_account.html">google_service_account</a> |
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.
nit: alignment
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.
Gah tabs v spaces in vim. Thanks!
var testAccGoogleServiceAccount_policy = ` | ||
resource "google_service_account" "acceptance" { | ||
account_id = "%v" | ||
display_name = "%v" |
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.
nit: alignment
|
||
Changing this updates the policy. | ||
|
||
Deleting this removes the policy, but leaves the original policy |
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.
nit: double space after original
```js | ||
resource "google_service_account" "object_viewer" { | ||
account_id = "object-viewer" | ||
display_name = "Object viewer" |
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.
nit: alignment
Thanks, @cblecker! Acceptance tests are good:
I know Mr @stack72 had need for service accounts recently. Perhaps he'd like to comment on this change and merge when ready? |
If @stack72 doesn't get a chance this week to make the call, I will. :) |
@stack72 passed this to me, so I'll have a response for it in the next few days. :) |
} | ||
|
||
oldPStringf, _ := json.MarshalIndent(oldPString, "", " ") | ||
newPStringf, _ := json.MarshalIndent(newPString, "", " ") |
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 use json.MarshalIndent
here? It's being called on a string, so from my experiments, it would seem to have no effect that fmt.Printf("%q")
wouldn't. Also, ignoring the errors is making me nervous. I understand that it'll only effect debug outputs, but even just logging them and carrying on would make me feel better; at least we would have accurate debug output. :)
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.
Ooh, %q. That works!
Steps: []resource.TestStep{ | ||
// The first step creates a basic service account | ||
resource.TestStep{ | ||
Config: fmt.Sprintf(testAccGoogleServiceAccount_basic, accountId, displayName), |
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 pattern I've seen is that these get implemented as functions, with accountId
and displayName
passed in as arguments and the Config string returned, instead of as fmt.Sprintf
strings. This seems like a better option to me, as it documents the requirements and should they change after this is reused, it won't build unless you update them everywhere. With the Sprintf
string, it'll just have weird output.
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.
Great catch. Fixed.
return fmt.Errorf("Not found: %s", r) | ||
} | ||
|
||
if rs.Primary.Attributes["display_name"] != displayName2 { |
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'm probably missing something basic here, but why make displayName2
global mutable state instead of passing it in as an argument, as you did for testAccCheckGoogleServiceAccountPolicyCount
?
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.
You're not missing anything; I missed that in a refactor.
|
||
# google\_service\_account | ||
|
||
Allows management of a Google Cloud Platform service account. |
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.
Maybe link to service account docs?
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.
Done.
Changing this updates the policy. | ||
|
||
Deleting this removes the policy, but leaves the original policy | ||
intact. If there are overlapping `binding` entries between the original |
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.
What is the "original policy" in this case? I'm somewhat familiar with service accounts, but I'm confused about what happens when deleting the policy.
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.
Clarified.
Sorry for the delay. Got around to reviewing this, and I had a few questions. They may not require code changes at all, it's entirely possible I'm missing things. :) Let me know if you have any questions or disagree with any of my feedback. And thanks for taking the time to submit the new resource! |
Thanks, @paddyforan. Great feedback, and prompt. I really appreciate it. Just pushed a new change that addresses them all. |
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.
Thanks for the speedy update on the code. Glad the review was helpful.
This looks good to me, so I'll go ahead and merge it. Super glad we got this in, and thanks again for contributing it!
intact. If there are overlapping `binding` entries between the original | ||
policy and the data source policy, they will be removed. | ||
Deleting this removes the policy declared in Terraform. Any policy bindings | ||
associated with the project before Terraform was used are not deleted. |
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.
That makes so much more sense to me now. :D
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. |
This change adds support for the
google_service_account
resource. Thegoogle_service_account
allows a Terraform user to create, modify, and delete Service Accounts on Google Cloud Platform.