mmv1/products/appengine/FlexibleAppVersion.yaml (817 lines of code) (raw):

# Copyright 2024 Google Inc. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. --- name: 'FlexibleAppVersion' api_resource_type_kind: Version description: | Flexible App Version resource to create a new version of flexible GAE Application. Based on Google Compute Engine, the App Engine flexible environment automatically scales your app up and down while also balancing the load. Learn about the differences between the standard environment and the flexible environment at https://cloud.google.com/appengine/docs/the-appengine-environments. ~> **Note:** The App Engine flexible environment service account uses the member ID `service-[YOUR_PROJECT_NUMBER]@gae-api-prod.google.com.iam.gserviceaccount.com` It should have the App Engine Flexible Environment Service Agent role, which will be applied when the `appengineflex.googleapis.com` service is enabled. references: guides: 'Official Documentation': 'https://cloud.google.com/appengine/docs/flexible' api: 'https://cloud.google.com/appengine/docs/admin-api/reference/rest/v1/apps.services.versions' docs: id_format: 'apps/{{project}}/services/{{service}}/versions/{{version_id}}' base_url: 'apps/{{project}}/services/{{service}}/versions' self_link: 'apps/{{project}}/services/{{service}}/versions/{{version_id}}?view=FULL' update_url: 'apps/{{project}}/services/{{service}}/versions' update_verb: 'POST' update_mask: false delete_url: 'apps/{{project}}/services/{{service}}/versions/{{version_id}}' mutex: 'apps/{{project}}' import_format: - 'apps/{{project}}/services/{{service}}/versions/{{version_id}}' timeouts: insert_minutes: 20 update_minutes: 20 delete_minutes: 20 async: actions: ['create', 'delete', 'update'] type: 'OpAsync' operation: base_url: '{{op_id}}' result: resource_inside_response: false collection_url_key: 'versions' custom_code: encoder: 'templates/terraform/encoders/flex_app_version.go.tmpl' custom_delete: 'templates/terraform/custom_delete/appversion_delete.go.tmpl' test_check_destroy: 'templates/terraform/custom_check_destroy/skip_delete_during_test.go.tmpl' error_retry_predicates: - 'transport_tpg.IsAppEngineRetryableError' examples: - name: 'app_engine_flexible_app_version' primary_resource_id: 'myapp_v1' vars: bucket_name: 'appengine-static-content' project: 'appeng-flex' account_id: 'my-account' test_env_vars: org_id: 'ORG_ID' billing_account: 'BILLING_ACCT' ignore_read_extra: - 'noop_on_destroy' - 'deployment.0.zip' # https://github.com/hashicorp/terraform-provider-google/issues/19040 exclude_test: true virtual_fields: - name: 'noop_on_destroy' description: | If set to `true`, the application version will not be deleted. type: Boolean default_value: false - name: 'delete_service_on_destroy' description: | If set to `true`, the service will be deleted if it is the last version. type: Boolean default_value: false parameters: - name: 'service' type: ResourceRef description: | AppEngine service resource. Can contain numbers, letters, and hyphens. url_param_only: true required: true resource: 'Service' imports: 'name' properties: - name: 'name' type: String description: | Full path to the Version resource in the API. Example, "v1". output: true - name: 'version_id' type: String description: | Relative name of the version within the service. For example, `v1`. Version names can contain only lowercase letters, numbers, or hyphens. Reserved names,"default", "latest", and any name with the prefix "ah-". api_name: id immutable: true - name: 'inboundServices' type: Array description: | A list of the types of messages that this application is able to receive. is_set: true item_type: type: Enum description: | One type of message that this application is able to receive. enum_values: - 'INBOUND_SERVICE_MAIL' - 'INBOUND_SERVICE_MAIL_BOUNCE' - 'INBOUND_SERVICE_XMPP_ERROR' - 'INBOUND_SERVICE_XMPP_MESSAGE' - 'INBOUND_SERVICE_XMPP_SUBSCRIBE' - 'INBOUND_SERVICE_XMPP_PRESENCE' - 'INBOUND_SERVICE_CHANNEL_PRESENCE' - 'INBOUND_SERVICE_WARMUP' - name: 'instanceClass' type: String description: | Instance class that is used to run this version. Valid values are AutomaticScaling: F1, F2, F4, F4_1G ManualScaling: B1, B2, B4, B8, B4_1G Defaults to F1 for AutomaticScaling and B1 for ManualScaling. - name: 'network' type: NestedObject description: Extra network settings properties: - name: 'forwardedPorts' type: Array description: | List of ports, or port pairs, to forward from the virtual machine to the application container. item_type: type: String - name: 'instanceIpMode' type: Enum description: | Prevent instances from receiving an ephemeral external IP address. min_version: 'beta' enum_values: - 'EXTERNAL' - 'INTERNAL' - name: 'instanceTag' type: String description: | Tag to apply to the instance during creation. - name: 'name' type: String description: | Google Compute Engine network where the virtual machines are created. Specify the short name, not the resource path. required: true - name: 'subnetwork' type: String description: | Google Cloud Platform sub-network where the virtual machines are created. Specify the short name, not the resource path. If the network that the instance is being created in is a Legacy network, then the IP address is allocated from the IPv4Range. If the network that the instance is being created in is an auto Subnet Mode Network, then only network name should be specified (not the subnetworkName) and the IP address is created from the IPCidrRange of the subnetwork that exists in that zone for that network. If the network that the instance is being created in is a custom Subnet Mode Network, then the subnetworkName must be specified and the IP address is created from the IPCidrRange of the subnetwork. If specified, the subnetwork must exist in the same region as the App Engine flexible environment application. api_name: subnetworkName - name: 'sessionAffinity' type: Boolean description: | Enable session affinity. - name: 'resources' type: NestedObject description: Machine resources for a version. properties: - name: 'cpu' type: Integer description: | Number of CPU cores needed. at_least_one_of: - 'resources.0.cpu' - 'resources.0.disk_gb' - 'resources.0.memory_gb' - 'resources.0.volumes' - name: 'diskGb' type: Integer description: | Disk size (GB) needed. at_least_one_of: - 'resources.0.cpu' - 'resources.0.disk_gb' - 'resources.0.memory_gb' - 'resources.0.volumes' - name: 'memoryGb' type: Double description: | Memory (GB) needed. at_least_one_of: - 'resources.0.cpu' - 'resources.0.disk_gb' - 'resources.0.memory_gb' - 'resources.0.volumes' - name: 'volumes' type: Array description: | List of ports, or port pairs, to forward from the virtual machine to the application container. at_least_one_of: - 'resources.0.cpu' - 'resources.0.disk_gb' - 'resources.0.memory_gb' - 'resources.0.volumes' item_type: type: NestedObject properties: - name: 'name' type: String description: | Unique name for the volume. required: true - name: 'volumeType' type: String description: | Underlying volume type, e.g. 'tmpfs'. required: true - name: 'sizeGb' type: Integer description: | Volume size in gigabytes. required: true - name: 'runtime' type: String description: | Desired runtime. Example python27. required: true - name: 'runtimeChannel' type: String description: | The channel of the runtime to use. Only available for some runtimes. - name: 'flexibleRuntimeSettings' type: NestedObject description: Runtime settings for App Engine flexible environment. properties: - name: 'operatingSystem' type: String description: | Operating System of the application runtime. - name: 'runtimeVersion' type: String description: | The runtime version of an App Engine flexible application. - name: 'betaSettings' type: KeyValuePairs description: | Metadata settings that are supplied to this version to enable beta runtime features. ignore_read: true - name: 'servingStatus' type: Enum description: | Current serving status of this version. Only the versions with a SERVING status create instances and can be billed. default_value: "SERVING" enum_values: - 'SERVING' - 'STOPPED' - name: 'runtimeApiVersion' type: String description: | The version of the API in the given runtime environment. Please see the app.yaml reference for valid values at `https://cloud.google.com/appengine/docs/standard/<language>/config/appref`\ Substitute `<language>` with `python`, `java`, `php`, `ruby`, `go` or `nodejs`. default_from_api: true - name: 'handlers' type: Array description: | An ordered list of URL-matching patterns that should be applied to incoming requests. The first matching URL handles the request and other request handlers are not attempted. default_from_api: true item_type: type: NestedObject properties: - name: 'urlRegex' type: String description: | URL prefix. Uses regular expression syntax, which means regexp special characters must be escaped, but should not contain groupings. All URLs that begin with this prefix are handled by this handler, using the portion of the URL after the prefix as part of the file path. - name: 'securityLevel' type: Enum description: | Security (HTTPS) enforcement for this URL. required: false enum_values: - 'SECURE_DEFAULT' - 'SECURE_NEVER' - 'SECURE_OPTIONAL' - 'SECURE_ALWAYS' - name: 'login' type: Enum description: | Methods to restrict access to a URL based on login status. required: false enum_values: - 'LOGIN_OPTIONAL' - 'LOGIN_ADMIN' - 'LOGIN_REQUIRED' - name: 'authFailAction' type: Enum description: | Actions to take when the user is not logged in. required: false enum_values: - 'AUTH_FAIL_ACTION_REDIRECT' - 'AUTH_FAIL_ACTION_UNAUTHORIZED' - name: 'redirectHttpResponseCode' type: Enum description: | 30x code to use when performing redirects for the secure field. required: false enum_values: - 'REDIRECT_HTTP_RESPONSE_CODE_301' - 'REDIRECT_HTTP_RESPONSE_CODE_302' - 'REDIRECT_HTTP_RESPONSE_CODE_303' - 'REDIRECT_HTTP_RESPONSE_CODE_307' - name: 'script' type: NestedObject # TODO (mbang): Exactly one of script, staticFiles, or apiEndpoint must be set description: | Executes a script to handle the requests that match this URL pattern. Only the auto value is supported for Node.js in the App Engine standard environment, for example "script:" "auto". properties: - name: 'scriptPath' type: String description: | Path to the script from the application root directory. required: true - name: 'staticFiles' type: NestedObject # TODO (mbang): Exactly one of script, staticFiles, or apiEndpoint must be set description: | Files served directly to the user for a given URL, such as images, CSS stylesheets, or JavaScript source files. Static file handlers describe which files in the application directory are static files, and which URLs serve them. properties: - name: 'path' type: String description: | Path to the static files matched by the URL pattern, from the application root directory. The path can refer to text matched in groupings in the URL pattern. - name: 'uploadPathRegex' type: String description: | Regular expression that matches the file paths for all files that should be referenced by this handler. - name: 'httpHeaders' type: KeyValuePairs description: | HTTP headers to use for all responses from these URLs. An object containing a list of "key:value" value pairs.". - name: 'mimeType' type: String description: | MIME type used to serve all files served by this handler. Defaults to file-specific MIME types, which are derived from each file's filename extension. - name: 'expiration' type: String description: | Time a static file served by this handler should be cached by web proxies and browsers. A duration in seconds with up to nine fractional digits, terminated by 's'. Example "3.5s". Default is '0s' default_value: "0s" - name: 'requireMatchingFile' type: Boolean description: | Whether this handler should match the request if the file referenced by the handler does not exist. - name: 'applicationReadable' type: Boolean description: | Whether files should also be uploaded as code data. By default, files declared in static file handlers are uploaded as static data and are only served to end users; they cannot be read by the application. If enabled, uploads are charged against both your code and static data storage resource quotas. - name: 'runtimeMainExecutablePath' type: String description: | The path or name of the app's main executable. - name: 'serviceAccount' type: String description: | The identity that the deployed version will run as. Admin API will use the App Engine Appspot service account as default if this field is neither provided in app.yaml file nor through CLI flag. default_from_api: true - name: 'apiConfig' type: NestedObject description: | Serving configuration for Google Cloud Endpoints. properties: - name: 'authFailAction' type: Enum description: | Action to take when users access resources that require authentication. default_value: "AUTH_FAIL_ACTION_REDIRECT" enum_values: - 'AUTH_FAIL_ACTION_REDIRECT' - 'AUTH_FAIL_ACTION_UNAUTHORIZED' - name: 'login' type: Enum description: | Level of login required to access this resource. default_value: "LOGIN_OPTIONAL" enum_values: - 'LOGIN_OPTIONAL' - 'LOGIN_ADMIN' - 'LOGIN_REQUIRED' - name: 'script' type: String description: | Path to the script from the application root directory. required: true - name: 'securityLevel' type: Enum description: | Security (HTTPS) enforcement for this URL. enum_values: - 'SECURE_DEFAULT' - 'SECURE_NEVER' - 'SECURE_OPTIONAL' - 'SECURE_ALWAYS' - name: 'url' type: String description: | URL to serve the endpoint at. - name: 'envVariables' type: KeyValuePairs description: |- Environment variables available to the application. As these are not returned in the API request, Terraform will not detect any changes made outside of the Terraform config. ignore_read: true - name: 'defaultExpiration' type: String description: | Duration that static files should be cached by web proxies and browsers. Only applicable if the corresponding StaticFilesHandler does not specify its own expiration time. - name: 'readinessCheck' type: NestedObject description: | Configures readiness health checking for instances. Unhealthy instances are not put into the backend traffic rotation. required: true properties: - name: 'path' type: String description: | The request path. required: true - name: 'host' type: String description: | Host header to send when performing a HTTP Readiness check. Example: "myapp.appspot.com" - name: 'failureThreshold' type: Double description: | Number of consecutive failed checks required before removing traffic. Default: 2. default_value: 2.0 - name: 'successThreshold' type: Double description: | Number of consecutive successful checks required before receiving traffic. Default: 2. default_value: 2.0 - name: 'checkInterval' type: String description: | Interval between health checks. Default: "5s". default_value: "5s" - name: 'timeout' type: String description: | Time before the check is considered failed. Default: "4s" default_value: "4s" - name: 'appStartTimeout' type: String description: | A maximum time limit on application initialization, measured from moment the application successfully replies to a healthcheck until it is ready to serve traffic. Default: "300s" default_value: "300s" - name: 'livenessCheck' type: NestedObject description: | Health checking configuration for VM instances. Unhealthy instances are killed and replaced with new instances. required: true properties: - name: 'path' type: String description: | The request path. required: true - name: 'host' type: String description: | Host header to send when performing a HTTP Readiness check. Example: "myapp.appspot.com" - name: 'failureThreshold' type: Double description: | Number of consecutive failed checks required before considering the VM unhealthy. Default: 4. default_value: 4.0 - name: 'successThreshold' type: Double description: | Number of consecutive successful checks required before considering the VM healthy. Default: 2. default_value: 2.0 - name: 'checkInterval' type: String description: | Interval between health checks. default_value: "30s" - name: 'timeout' type: String description: | Time before the check is considered failed. Default: "4s" default_value: "4s" - name: 'initialDelay' type: String description: | The initial delay before starting to execute the checks. Default: "300s" default_value: "300s" - name: 'nobuildFilesRegex' type: String description: | Files that match this pattern will not be built into this version. Only applicable for Go runtimes. - name: 'deployment' type: NestedObject description: | Code and application artifacts that make up this version. ignore_read: true properties: - name: 'zip' type: NestedObject description: 'Zip File' at_least_one_of: - 'deployment.0.zip' - 'deployment.0.files' - 'deployment.0.container' properties: - name: 'sourceUrl' type: String description: 'Source URL' required: true - name: 'filesCount' type: Integer description: 'files count' - name: 'files' type: Map description: | Manifest of the files stored in Google Cloud Storage that are included as part of this version. All files must be readable using the credentials supplied with this call. at_least_one_of: - 'deployment.0.zip' - 'deployment.0.files' - 'deployment.0.container' key_name: 'name' key_description: | name of file value_type: name: files type: NestedObject properties: - name: 'sha1Sum' type: String description: | SHA1 checksum of the file - name: 'sourceUrl' type: String description: | Source URL required: true - name: 'container' type: NestedObject description: 'The Docker image for the container that runs the version.' default_from_api: true at_least_one_of: - 'deployment.0.zip' - 'deployment.0.files' - 'deployment.0.container' properties: - name: 'image' type: String description: | URI to the hosted container image in Google Container Registry. The URI must be fully qualified and include a tag or digest. Examples: "gcr.io/my-project/image:tag" or "gcr.io/my-project/image@digest" required: true - name: 'cloudBuildOptions' type: NestedObject description: Options for the build operations performed as a part of the version deployment. Only applicable when creating a version using source code directly. at_least_one_of: - 'deployment.0.zip' - 'deployment.0.files' - 'deployment.0.container' properties: - name: 'appYamlPath' type: String description: | Path to the yaml file used in deployment, used to determine runtime configuration details. required: true - name: 'cloudBuildTimeout' type: String description: | The Cloud Build timeout used as part of any dependent builds performed by version creation. Defaults to 10 minutes. A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s". - name: 'endpointsApiService' type: NestedObject description: | Code and application artifacts that make up this version. properties: - name: 'name' type: String description: | Endpoints service name which is the name of the "service" resource in the Service Management API. For example "myapi.endpoints.myproject.cloud.goog" required: true - name: 'configId' type: String description: | Endpoints service configuration ID as specified by the Service Management API. For example "2016-09-19r1". By default, the rollout strategy for Endpoints is "FIXED". This means that Endpoints starts up with a particular configuration ID. When a new configuration is rolled out, Endpoints must be given the new configuration ID. The configId field is used to give the configuration ID and is required in this case. Endpoints also has a rollout strategy called "MANAGED". When using this, Endpoints fetches the latest configuration and does not need the configuration ID. In this case, configId must be omitted. - name: 'rolloutStrategy' type: Enum description: | Endpoints rollout strategy. If FIXED, configId must be specified. If MANAGED, configId must be omitted. default_value: "FIXED" enum_values: - 'FIXED' - 'MANAGED' - name: 'disableTraceSampling' type: Boolean description: Enable or disable trace sampling. By default, this is set to false for enabled. default_value: false - name: 'entrypoint' type: NestedObject description: | The entrypoint for the application. ignore_read: true properties: - name: 'shell' type: String description: | The format should be a shell command that can be fed to bash -c. required: true - name: 'vpcAccessConnector' type: NestedObject description: | Enables VPC connectivity for standard apps. properties: - name: 'name' type: String description: | Full Serverless VPC Access Connector name e.g. /projects/my-project/locations/us-central1/connectors/c1. required: true - name: 'automaticScaling' type: NestedObject description: | Automatic scaling is based on request rate, response latencies, and other application metrics. exactly_one_of: - 'automatic_scaling' - 'manual_scaling' properties: - name: 'coolDownPeriod' type: String description: | The time period that the Autoscaler should wait before it starts collecting information from a new instance. This prevents the autoscaler from collecting information when the instance is initializing, during which the collected usage would not be reliable. Default: 120s default_value: "120s" - name: 'cpuUtilization' type: NestedObject description: | Target scaling by CPU usage. required: true properties: - name: 'aggregationWindowLength' type: String description: | Period of time over which CPU utilization is calculated. - name: 'targetUtilization' type: Double description: | Target CPU utilization ratio to maintain when scaling. Must be between 0 and 1. required: true - name: 'maxConcurrentRequests' type: Integer description: | Number of concurrent requests an automatic scaling instance can accept before the scheduler spawns a new instance. Defaults to a runtime-specific value. default_from_api: true - name: 'maxIdleInstances' type: Integer description: | Maximum number of idle instances that should be maintained for this version. - name: 'maxTotalInstances' type: Integer description: | Maximum number of instances that should be started to handle requests for this version. Default: 20 default_value: 20 - name: 'maxPendingLatency' type: String description: | Maximum amount of time that a request should wait in the pending queue before starting a new instance to handle it. - name: 'minIdleInstances' type: Integer description: | Minimum number of idle instances that should be maintained for this version. Only applicable for the default version of a service. - name: 'minTotalInstances' type: Integer description: | Minimum number of running instances that should be maintained for this version. Default: 2 default_value: 2 - name: 'minPendingLatency' type: String description: | Minimum amount of time a request should wait in the pending queue before starting a new instance to handle it. - name: 'requestUtilization' type: NestedObject description: | Target scaling by request utilization. properties: - name: 'targetRequestCountPerSecond' type: String description: | Target requests per second. at_least_one_of: - 'automatic_scaling.0.request_utilization.0.target_request_count_per_second' - 'automatic_scaling.0.request_utilization.0.target_concurrent_requests' - name: 'targetConcurrentRequests' type: Double description: | Target number of concurrent requests. at_least_one_of: - 'automatic_scaling.0.request_utilization.0.target_request_count_per_second' - 'automatic_scaling.0.request_utilization.0.target_concurrent_requests' - name: 'diskUtilization' type: NestedObject description: | Target scaling by disk usage. properties: - name: 'targetWriteBytesPerSecond' type: Integer description: | Target bytes written per second. at_least_one_of: - 'automatic_scaling.0.disk_utilization.0.target_write_bytes_per_second' - 'automatic_scaling.0.disk_utilization.0.target_write_ops_per_second' - 'automatic_scaling.0.disk_utilization.0.target_read_bytes_per_second' - 'automatic_scaling.0.disk_utilization.0.target_read_ops_per_second' - name: 'targetWriteOpsPerSecond' type: Integer description: | Target ops written per second. at_least_one_of: - 'automatic_scaling.0.disk_utilization.0.target_write_bytes_per_second' - 'automatic_scaling.0.disk_utilization.0.target_write_ops_per_second' - 'automatic_scaling.0.disk_utilization.0.target_read_bytes_per_second' - 'automatic_scaling.0.disk_utilization.0.target_read_ops_per_second' - name: 'targetReadBytesPerSecond' type: Integer description: | Target bytes read per second. at_least_one_of: - 'automatic_scaling.0.disk_utilization.0.target_write_bytes_per_second' - 'automatic_scaling.0.disk_utilization.0.target_write_ops_per_second' - 'automatic_scaling.0.disk_utilization.0.target_read_bytes_per_second' - 'automatic_scaling.0.disk_utilization.0.target_read_ops_per_second' - name: 'targetReadOpsPerSecond' type: Integer description: | Target ops read per seconds. at_least_one_of: - 'automatic_scaling.0.disk_utilization.0.target_write_bytes_per_second' - 'automatic_scaling.0.disk_utilization.0.target_write_ops_per_second' - 'automatic_scaling.0.disk_utilization.0.target_read_bytes_per_second' - 'automatic_scaling.0.disk_utilization.0.target_read_ops_per_second' - name: 'networkUtilization' type: NestedObject description: | Target scaling by network usage. properties: - name: 'targetSentBytesPerSecond' type: Integer description: | Target bytes sent per second. at_least_one_of: - 'automatic_scaling.0.network_utilization.0.target_sent_bytes_per_second' - 'automatic_scaling.0.network_utilization.0.target_sent_packets_per_second' - 'automatic_scaling.0.network_utilization.0.target_received_bytes_per_second' - 'automatic_scaling.0.network_utilization.0.target_received_packets_per_second' - name: 'targetSentPacketsPerSecond' type: Integer description: | Target packets sent per second. at_least_one_of: - 'automatic_scaling.0.network_utilization.0.target_sent_bytes_per_second' - 'automatic_scaling.0.network_utilization.0.target_sent_packets_per_second' - 'automatic_scaling.0.network_utilization.0.target_received_bytes_per_second' - 'automatic_scaling.0.network_utilization.0.target_received_packets_per_second' - name: 'targetReceivedBytesPerSecond' type: Integer description: | Target bytes received per second. at_least_one_of: - 'automatic_scaling.0.network_utilization.0.target_sent_bytes_per_second' - 'automatic_scaling.0.network_utilization.0.target_sent_packets_per_second' - 'automatic_scaling.0.network_utilization.0.target_received_bytes_per_second' - 'automatic_scaling.0.network_utilization.0.target_received_packets_per_second' - name: 'targetReceivedPacketsPerSecond' type: Integer description: | Target packets received per second. at_least_one_of: - 'automatic_scaling.0.network_utilization.0.target_sent_bytes_per_second' - 'automatic_scaling.0.network_utilization.0.target_sent_packets_per_second' - 'automatic_scaling.0.network_utilization.0.target_received_bytes_per_second' - 'automatic_scaling.0.network_utilization.0.target_received_packets_per_second' - name: 'manualScaling' type: NestedObject description: | A service with manual scaling runs continuously, allowing you to perform complex initialization and rely on the state of its memory over time. exactly_one_of: - 'automatic_scaling' - 'manual_scaling' properties: - name: 'instances' type: Integer description: | Number of instances to assign to the service at the start. **Note:** When managing the number of instances at runtime through the App Engine Admin API or the (now deprecated) Python 2 Modules API set_num_instances() you must use `lifecycle.ignore_changes = ["manual_scaling"[0].instances]` to prevent drift detection. required: true