@@ -260,25 +260,26 @@ func resourceBigtableInstanceRead(d *schema.ResourceData, meta interface{}) erro
260260
261261 ctxWithTimeout , cancel := context .WithTimeout (ctx , d .Timeout (schema .TimeoutRead ))
262262 defer cancel ()
263- instance , err := c .InstanceInfo (ctxWithTimeout , instanceName )
264- if err != nil {
265- if tpgresource .IsNotFoundGrpcError (err ) {
266- log .Printf ("[WARN] Removing %s because it's gone" , instanceName )
267- d .SetId ("" )
268- return nil
269- }
263+ instancesResponse , err := c .Instances (ctxWithTimeout )
264+ instance , stop , err := getInstanceFromResponse (instancesResponse , instanceName , err , d )
265+ if stop {
270266 return err
271267 }
272268
273269 if err := d .Set ("project" , project ); err != nil {
274270 return fmt .Errorf ("Error setting project: %s" , err )
275271 }
276272
277- clusters , err := c .Clusters (ctxWithTimeout , instance . Name )
273+ clusters , err := c .Clusters (ctxWithTimeout , instanceName )
278274 if err != nil {
279275 partiallyUnavailableErr , ok := err .(bigtable.ErrPartiallyUnavailable )
280-
281276 if ! ok {
277+ // Clusters() fails with 404 if instance does not exist.
278+ if tpgresource .IsNotFoundGrpcError (err ) {
279+ log .Printf ("[WARN] Removing %s because it's gone" , instanceName )
280+ d .SetId ("" )
281+ return nil
282+ }
282283 return fmt .Errorf ("Error retrieving instance clusters. %s" , err )
283284 }
284285
@@ -432,6 +433,42 @@ func flattenBigtableCluster(c *bigtable.ClusterInfo) map[string]interface{} {
432433 return cluster
433434}
434435
436+ func getInstanceFromResponse (instances []* bigtable.InstanceInfo , instanceName string , err error , d * schema.ResourceData ) (* bigtable.InstanceInfo , bool , error ) {
437+ // Fail on any error other than ParrtiallyUnavailable.
438+ isPartiallyUnavailableError := false
439+ if err != nil {
440+ _ , isPartiallyUnavailableError = err .(bigtable.ErrPartiallyUnavailable )
441+
442+ if ! isPartiallyUnavailableError {
443+ return nil , true , fmt .Errorf ("Error retrieving instance. %s" , err )
444+ }
445+ }
446+
447+ // Get instance from response.
448+ var instanceInfo * bigtable.InstanceInfo
449+ for _ , instance := range instances {
450+ if instance .Name == instanceName {
451+ instanceInfo = instance
452+ }
453+ }
454+
455+ // If instance found, it either wasn't affected by the outage, or there is no outage.
456+ if instanceInfo != nil {
457+ return instanceInfo , false , nil
458+ }
459+
460+ // If instance wasn't found and error is PartiallyUnavailable,
461+ // continue to clusters call that will reveal overlap between instance regions and unavailable regions.
462+ if isPartiallyUnavailableError {
463+ return nil , false , nil
464+ }
465+
466+ // If instance wasn't found and error is not PartiallyUnavailable, instance doesn't exist.
467+ log .Printf ("[WARN] Removing %s because it's gone" , instanceName )
468+ d .SetId ("" )
469+ return nil , true , nil
470+ }
471+
435472func getUnavailableClusterZones (clusters []interface {}, unavailableZones []string ) []string {
436473 var zones []string
437474
0 commit comments