@@ -223,7 +223,55 @@ If not specified, gRPC health check follows behavior specified in 'port' and
223223 },
224224 },
225225 },
226- ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" },
226+ ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" , "grpc_tls_health_check" },
227+ },
228+ "grpc_tls_health_check" : {
229+ Type : schema .TypeList ,
230+ Optional : true ,
231+ DiffSuppressFunc : portDiffSuppress ,
232+ Description : `A nested object resource.` ,
233+ MaxItems : 1 ,
234+ Elem : & schema.Resource {
235+ Schema : map [string ]* schema.Schema {
236+ "grpc_service_name" : {
237+ Type : schema .TypeString ,
238+ Optional : true ,
239+ Description : `The gRPC service name for the health check.
240+ The value of grpcServiceName has the following meanings by convention:
241+ - Empty serviceName means the overall status of all services at the backend.
242+ - Non-empty serviceName means the health of that gRPC service, as defined by the owner of the service.
243+ The grpcServiceName can only be ASCII.` ,
244+ AtLeastOneOf : []string {"grpc_tls_health_check.0.port" , "grpc_tls_health_check.0.port_specification" , "grpc_tls_health_check.0.grpc_service_name" },
245+ },
246+ "port" : {
247+ Type : schema .TypeInt ,
248+ Optional : true ,
249+ Description : `The port number for the health check request.
250+ Must be specified if port_specification is USE_FIXED_PORT. Valid values are 1 through 65535.` ,
251+ AtLeastOneOf : []string {"grpc_tls_health_check.0.port" , "grpc_tls_health_check.0.port_specification" , "grpc_tls_health_check.0.grpc_service_name" },
252+ },
253+ "port_specification" : {
254+ Type : schema .TypeString ,
255+ Optional : true ,
256+ ValidateFunc : verify .ValidateEnum ([]string {"USE_FIXED_PORT" , "USE_NAMED_PORT" , "USE_SERVING_PORT" , "" }),
257+ Description : `Specifies how port is selected for health checking, can be one of the
258+ following values:
259+
260+ * 'USE_FIXED_PORT': The port number in 'port' is used for health checking.
261+
262+ * 'USE_NAMED_PORT': Not supported for GRPC with TLS health checking.
263+
264+ * 'USE_SERVING_PORT': For NetworkEndpointGroup, the port specified for each
265+ network endpoint is used for health checking. For other backends, the
266+ port or named port specified in the Backend Service is used for health
267+ checking.
268+
269+ If not specified, gRPC with TLS health check follows behavior specified in the 'port' field. Possible values: ["USE_FIXED_PORT", "USE_NAMED_PORT", "USE_SERVING_PORT"]` ,
270+ AtLeastOneOf : []string {"grpc_tls_health_check.0.port" , "grpc_tls_health_check.0.port_specification" , "grpc_tls_health_check.0.grpc_service_name" },
271+ },
272+ },
273+ },
274+ ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" , "grpc_tls_health_check" },
227275 },
228276 "healthy_threshold" : {
229277 Type : schema .TypeInt ,
@@ -309,7 +357,7 @@ can only be ASCII.`,
309357 },
310358 },
311359 },
312- ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" },
360+ ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" , "grpc_tls_health_check" },
313361 },
314362 "http_health_check" : {
315363 Type : schema .TypeList ,
@@ -388,7 +436,7 @@ can only be ASCII.`,
388436 },
389437 },
390438 },
391- ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" },
439+ ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" , "grpc_tls_health_check" },
392440 },
393441 "https_health_check" : {
394442 Type : schema .TypeList ,
@@ -467,7 +515,7 @@ can only be ASCII.`,
467515 },
468516 },
469517 },
470- ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" },
518+ ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" , "grpc_tls_health_check" },
471519 },
472520 "log_config" : {
473521 Type : schema .TypeList ,
@@ -583,7 +631,7 @@ can only be ASCII.`,
583631 },
584632 },
585633 },
586- ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" },
634+ ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" , "grpc_tls_health_check" },
587635 },
588636 "tcp_health_check" : {
589637 Type : schema .TypeList ,
@@ -655,7 +703,7 @@ can only be ASCII.`,
655703 },
656704 },
657705 },
658- ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" },
706+ ExactlyOneOf : []string {"http_health_check" , "https_health_check" , "http2_health_check" , "tcp_health_check" , "ssl_health_check" , "grpc_health_check" , "grpc_tls_health_check" },
659707 },
660708 "timeout_sec" : {
661709 Type : schema .TypeInt ,
@@ -783,6 +831,12 @@ func resourceComputeHealthCheckCreate(d *schema.ResourceData, meta interface{})
783831 } else if v , ok := d .GetOkExists ("grpc_health_check" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (grpcHealthCheckProp )) && (ok || ! reflect .DeepEqual (v , grpcHealthCheckProp )) {
784832 obj ["grpcHealthCheck" ] = grpcHealthCheckProp
785833 }
834+ grpcTlsHealthCheckProp , err := expandComputeHealthCheckGrpcTlsHealthCheck (d .Get ("grpc_tls_health_check" ), d , config )
835+ if err != nil {
836+ return err
837+ } else if v , ok := d .GetOkExists ("grpc_tls_health_check" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (grpcTlsHealthCheckProp )) && (ok || ! reflect .DeepEqual (v , grpcTlsHealthCheckProp )) {
838+ obj ["grpcTlsHealthCheck" ] = grpcTlsHealthCheckProp
839+ }
786840 logConfigProp , err := expandComputeHealthCheckLogConfig (d .Get ("log_config" ), d , config )
787841 if err != nil {
788842 return err
@@ -938,6 +992,9 @@ func resourceComputeHealthCheckRead(d *schema.ResourceData, meta interface{}) er
938992 if err := d .Set ("grpc_health_check" , flattenComputeHealthCheckGrpcHealthCheck (res ["grpcHealthCheck" ], d , config )); err != nil {
939993 return fmt .Errorf ("Error reading HealthCheck: %s" , err )
940994 }
995+ if err := d .Set ("grpc_tls_health_check" , flattenComputeHealthCheckGrpcTlsHealthCheck (res ["grpcTlsHealthCheck" ], d , config )); err != nil {
996+ return fmt .Errorf ("Error reading HealthCheck: %s" , err )
997+ }
941998 if err := d .Set ("log_config" , flattenComputeHealthCheckLogConfig (res ["logConfig" ], d , config )); err != nil {
942999 return fmt .Errorf ("Error reading HealthCheck: %s" , err )
9431000 }
@@ -1042,6 +1099,12 @@ func resourceComputeHealthCheckUpdate(d *schema.ResourceData, meta interface{})
10421099 } else if v , ok := d .GetOkExists ("grpc_health_check" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (v )) && (ok || ! reflect .DeepEqual (v , grpcHealthCheckProp )) {
10431100 obj ["grpcHealthCheck" ] = grpcHealthCheckProp
10441101 }
1102+ grpcTlsHealthCheckProp , err := expandComputeHealthCheckGrpcTlsHealthCheck (d .Get ("grpc_tls_health_check" ), d , config )
1103+ if err != nil {
1104+ return err
1105+ } else if v , ok := d .GetOkExists ("grpc_tls_health_check" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (v )) && (ok || ! reflect .DeepEqual (v , grpcTlsHealthCheckProp )) {
1106+ obj ["grpcTlsHealthCheck" ] = grpcTlsHealthCheckProp
1107+ }
10451108 logConfigProp , err := expandComputeHealthCheckLogConfig (d .Get ("log_config" ), d , config )
10461109 if err != nil {
10471110 return err
@@ -1625,6 +1688,48 @@ func flattenComputeHealthCheckGrpcHealthCheckGrpcServiceName(v interface{}, d *s
16251688 return v
16261689}
16271690
1691+ func flattenComputeHealthCheckGrpcTlsHealthCheck (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
1692+ if v == nil {
1693+ return nil
1694+ }
1695+ original := v .(map [string ]interface {})
1696+ if len (original ) == 0 {
1697+ return nil
1698+ }
1699+ transformed := make (map [string ]interface {})
1700+ transformed ["port" ] =
1701+ flattenComputeHealthCheckGrpcTlsHealthCheckPort (original ["port" ], d , config )
1702+ transformed ["port_specification" ] =
1703+ flattenComputeHealthCheckGrpcTlsHealthCheckPortSpecification (original ["portSpecification" ], d , config )
1704+ transformed ["grpc_service_name" ] =
1705+ flattenComputeHealthCheckGrpcTlsHealthCheckGrpcServiceName (original ["grpcServiceName" ], d , config )
1706+ return []interface {}{transformed }
1707+ }
1708+ func flattenComputeHealthCheckGrpcTlsHealthCheckPort (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
1709+ // Handles the string fixed64 format
1710+ if strVal , ok := v .(string ); ok {
1711+ if intVal , err := tpgresource .StringToFixed64 (strVal ); err == nil {
1712+ return intVal
1713+ }
1714+ }
1715+
1716+ // number values are represented as float64
1717+ if floatVal , ok := v .(float64 ); ok {
1718+ intVal := int (floatVal )
1719+ return intVal
1720+ }
1721+
1722+ return v // let terraform core handle it otherwise
1723+ }
1724+
1725+ func flattenComputeHealthCheckGrpcTlsHealthCheckPortSpecification (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
1726+ return v
1727+ }
1728+
1729+ func flattenComputeHealthCheckGrpcTlsHealthCheckGrpcServiceName (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
1730+ return v
1731+ }
1732+
16281733func flattenComputeHealthCheckLogConfig (v interface {}, d * schema.ResourceData , config * transport_tpg.Config ) interface {} {
16291734 transformed := make (map [string ]interface {})
16301735 if v == nil {
@@ -2163,6 +2268,54 @@ func expandComputeHealthCheckGrpcHealthCheckGrpcServiceName(v interface{}, d tpg
21632268 return v , nil
21642269}
21652270
2271+ func expandComputeHealthCheckGrpcTlsHealthCheck (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
2272+ if v == nil {
2273+ return nil , nil
2274+ }
2275+ l := v .([]interface {})
2276+ if len (l ) == 0 || l [0 ] == nil {
2277+ return nil , nil
2278+ }
2279+ raw := l [0 ]
2280+ original := raw .(map [string ]interface {})
2281+ transformed := make (map [string ]interface {})
2282+
2283+ transformedPort , err := expandComputeHealthCheckGrpcTlsHealthCheckPort (original ["port" ], d , config )
2284+ if err != nil {
2285+ return nil , err
2286+ } else if val := reflect .ValueOf (transformedPort ); val .IsValid () && ! tpgresource .IsEmptyValue (val ) {
2287+ transformed ["port" ] = transformedPort
2288+ }
2289+
2290+ transformedPortSpecification , err := expandComputeHealthCheckGrpcTlsHealthCheckPortSpecification (original ["port_specification" ], d , config )
2291+ if err != nil {
2292+ return nil , err
2293+ } else if val := reflect .ValueOf (transformedPortSpecification ); val .IsValid () && ! tpgresource .IsEmptyValue (val ) {
2294+ transformed ["portSpecification" ] = transformedPortSpecification
2295+ }
2296+
2297+ transformedGrpcServiceName , err := expandComputeHealthCheckGrpcTlsHealthCheckGrpcServiceName (original ["grpc_service_name" ], d , config )
2298+ if err != nil {
2299+ return nil , err
2300+ } else if val := reflect .ValueOf (transformedGrpcServiceName ); val .IsValid () && ! tpgresource .IsEmptyValue (val ) {
2301+ transformed ["grpcServiceName" ] = transformedGrpcServiceName
2302+ }
2303+
2304+ return transformed , nil
2305+ }
2306+
2307+ func expandComputeHealthCheckGrpcTlsHealthCheckPort (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
2308+ return v , nil
2309+ }
2310+
2311+ func expandComputeHealthCheckGrpcTlsHealthCheckPortSpecification (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
2312+ return v , nil
2313+ }
2314+
2315+ func expandComputeHealthCheckGrpcTlsHealthCheckGrpcServiceName (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
2316+ return v , nil
2317+ }
2318+
21662319func expandComputeHealthCheckLogConfig (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
21672320 if v == nil {
21682321 return nil , nil
@@ -2276,5 +2429,19 @@ func resourceComputeHealthCheckEncoder(d *schema.ResourceData, meta interface{},
22762429 return obj , nil
22772430 }
22782431
2432+ if _ , ok := d .GetOk ("grpc_tls_health_check" ); ok {
2433+ hc := d .Get ("grpc_tls_health_check" ).([]interface {})[0 ]
2434+ ps := hc .(map [string ]interface {})["port_specification" ]
2435+
2436+ if ps == "USE_FIXED_PORT" || ps == "" {
2437+ m := obj ["grpcTlsHealthCheck" ].(map [string ]interface {})
2438+ if m ["port" ] == nil {
2439+ return nil , fmt .Errorf ("error in HealthCheck %s: `port` must be set for GRPC with TLS health checks`." , d .Get ("name" ).(string ))
2440+ }
2441+ }
2442+ obj ["type" ] = "GRPC_WITH_TLS"
2443+ return obj , nil
2444+ }
2445+
22792446 return nil , fmt .Errorf ("error in HealthCheck %s: No health check block specified." , d .Get ("name" ).(string ))
22802447}
0 commit comments