Skip to content

Commit 12edd60

Browse files
Revert "Update service account creation to prevent failures due to eventual consistency" (#14506) (#23583)
[upstream:f89938e737ba53733ddfb484285f01f69eecdef2] Signed-off-by: Modular Magician <[email protected]>
1 parent 37f4536 commit 12edd60

File tree

2 files changed

+31
-37
lines changed

2 files changed

+31
-37
lines changed

.changelog/14506.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:note
2+
iam: Update service account creation to prevent failures due to eventual consistency (reverted)
3+
```

google/services/resourcemanager/resource_google_service_account.go

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -138,59 +138,54 @@ func resourceGoogleServiceAccountCreate(d *schema.ResourceData, meta interface{}
138138
ServiceAccount: sa,
139139
}
140140

141-
d.SetId(fmt.Sprintf("projects/%s/serviceAccounts/%s@%s.iam.gserviceaccount.com", project, aid, project))
142-
143-
iamClient := config.NewIamClient(userAgent)
144-
sa, err = iamClient.Projects.ServiceAccounts.Create("projects/"+project, r).Do()
141+
sa, err = config.NewIamClient(userAgent).Projects.ServiceAccounts.Create("projects/"+project, r).Do()
145142
if err != nil {
146143
gerr, ok := err.(*googleapi.Error)
147144
alreadyExists := ok && gerr.Code == 409 && d.Get("create_ignore_already_exists").(bool)
148145
if alreadyExists {
149-
err = transport_tpg.Retry(transport_tpg.RetryOptions{
150-
RetryFunc: func() (operr error) {
151-
sa, saerr := iamClient.Projects.ServiceAccounts.Get(d.Id()).Do()
152-
153-
if saerr != nil {
154-
return saerr
155-
}
156-
return populateResourceData(d, sa)
157-
},
158-
Timeout: d.Timeout(schema.TimeoutCreate),
159-
ErrorRetryPredicates: []transport_tpg.RetryErrorPredicateFunc{
160-
transport_tpg.IsNotFoundRetryableError("service account creation"),
161-
},
162-
})
163-
164-
return nil
146+
sa = &iam.ServiceAccount{
147+
Name: fmt.Sprintf("projects/%s/serviceAccounts/%s@%s.iam.gserviceaccount.com", project, aid, project),
148+
}
165149
} else {
166150
return fmt.Errorf("Error creating service account: %s", err)
167151
}
168152
}
169153

154+
d.SetId(sa.Name)
155+
156+
err = transport_tpg.Retry(transport_tpg.RetryOptions{
157+
RetryFunc: func() (operr error) {
158+
_, saerr := config.NewIamClient(userAgent).Projects.ServiceAccounts.Get(d.Id()).Do()
159+
return saerr
160+
},
161+
Timeout: d.Timeout(schema.TimeoutCreate),
162+
ErrorRetryPredicates: []transport_tpg.RetryErrorPredicateFunc{
163+
transport_tpg.IsNotFoundRetryableError("service account creation"),
164+
transport_tpg.IsForbiddenIamServiceAccountRetryableError("service account creation"),
165+
},
166+
})
167+
168+
if err != nil {
169+
return fmt.Errorf("Error reading service account after creation: %s", err)
170+
}
171+
170172
// We poll until the resource is found due to eventual consistency issue
171-
// on part of the api https://cloud.google.com/iam/docs/overview#consistency.
172-
// Wait for at least 3 successful responses in a row to ensure result is consistent.
173+
// on part of the api https://cloud.google.com/iam/docs/overview#consistency
173174
// IAM API returns 403 when the queried SA is not found, so we must ignore both 404 & 403 errors
174-
transport_tpg.PollingWaitTime(
175-
resourceServiceAccountPollRead(d, meta),
176-
transport_tpg.PollCheckForExistence,
177-
"Creating Service Account",
178-
d.Timeout(schema.TimeoutCreate),
179-
3, // Number of consecutive occurences.
180-
)
175+
err = transport_tpg.PollingWaitTime(resourceServiceAccountPollRead(d, meta), transport_tpg.PollCheckForExistenceWith403, "Creating Service Account", d.Timeout(schema.TimeoutCreate), 1)
181176

182-
populateResourceData(d, sa)
177+
if err != nil {
178+
return err
179+
}
183180

184181
// We can't guarantee complete consistency even after polling,
185182
// so sleep for some additional time to reduce the likelihood of
186183
// eventual consistency failures.
187184
time.Sleep(10 * time.Second)
188185

189-
return nil
186+
return resourceGoogleServiceAccountRead(d, meta)
190187
}
191188

192-
// PollReadFunc for checking Service Account existence.
193-
// If resourceData is not nil, it will be updated with the response.
194189
func resourceServiceAccountPollRead(d *schema.ResourceData, meta interface{}) transport_tpg.PollReadFunc {
195190
return func() (map[string]interface{}, error) {
196191
config := meta.(*transport_tpg.Config)
@@ -222,10 +217,6 @@ func resourceGoogleServiceAccountRead(d *schema.ResourceData, meta interface{})
222217
return transport_tpg.HandleNotFoundError(err, d, fmt.Sprintf("Service Account %q", d.Id()))
223218
}
224219

225-
return populateResourceData(d, sa)
226-
}
227-
228-
func populateResourceData(d *schema.ResourceData, sa *iam.ServiceAccount) error {
229220
if err := d.Set("email", sa.Email); err != nil {
230221
return fmt.Errorf("Error setting email: %s", err)
231222
}

0 commit comments

Comments
 (0)