@@ -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.
194189func 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