@@ -138,59 +138,54 @@ func resourceGoogleServiceAccountCreate(d *schema.ResourceData, meta interface{}
138
138
ServiceAccount : sa ,
139
139
}
140
140
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 ()
145
142
if err != nil {
146
143
gerr , ok := err .(* googleapi.Error )
147
144
alreadyExists := ok && gerr .Code == 409 && d .Get ("create_ignore_already_exists" ).(bool )
148
145
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
+ }
165
149
} else {
166
150
return fmt .Errorf ("Error creating service account: %s" , err )
167
151
}
168
152
}
169
153
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
+
170
172
// 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
173
174
// 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 )
181
176
182
- populateResourceData (d , sa )
177
+ if err != nil {
178
+ return err
179
+ }
183
180
184
181
// We can't guarantee complete consistency even after polling,
185
182
// so sleep for some additional time to reduce the likelihood of
186
183
// eventual consistency failures.
187
184
time .Sleep (10 * time .Second )
188
185
189
- return nil
186
+ return resourceGoogleServiceAccountRead ( d , meta )
190
187
}
191
188
192
- // PollReadFunc for checking Service Account existence.
193
- // If resourceData is not nil, it will be updated with the response.
194
189
func resourceServiceAccountPollRead (d * schema.ResourceData , meta interface {}) transport_tpg.PollReadFunc {
195
190
return func () (map [string ]interface {}, error ) {
196
191
config := meta .(* transport_tpg.Config )
@@ -222,10 +217,6 @@ func resourceGoogleServiceAccountRead(d *schema.ResourceData, meta interface{})
222
217
return transport_tpg .HandleNotFoundError (err , d , fmt .Sprintf ("Service Account %q" , d .Id ()))
223
218
}
224
219
225
- return populateResourceData (d , sa )
226
- }
227
-
228
- func populateResourceData (d * schema.ResourceData , sa * iam.ServiceAccount ) error {
229
220
if err := d .Set ("email" , sa .Email ); err != nil {
230
221
return fmt .Errorf ("Error setting email: %s" , err )
231
222
}
0 commit comments