Repository: apache/airflow

Issue:
ComputeEngineInsertInstanceOperator doesn't respect jinja-templated instance name when given in body argument 
### Apache Airflow version

2.7.0

### What happened

when initializing the operator with a `body` that has a jinja-templated `name` field and without a `resource_id`, the creation fails due to the fact that the instance name doesn't fit the name format - but that is because it doesnt go realization/jinja-parsing.

### What you think should happen instead

full error log:
```
[2023-09-06, 09:22:41 UTC] {taskinstance.py:1768} ERROR - Task failed with exception
Traceback (most recent call last):
  File "/home/sigal/.local/share/virtualenvs/ingest-airflow-rHPaIjXZ/lib/python3.8/site-packages/airflow/providers/google/cloud/operators/compute.py", line 210, in execute
    existing_instance = hook.get_instance(
  File "/home/sigal/.local/share/virtualenvs/ingest-airflow-rHPaIjXZ/lib/python3.8/site-packages/airflow/providers/google/common/hooks/base_google.py", line 468, in inner_wrapper
    return func(self, *args, **kwargs)
  File "/home/sigal/.local/share/virtualenvs/ingest-airflow-rHPaIjXZ/lib/python3.8/site-packages/airflow/providers/google/cloud/hooks/compute.py", line 350, in get_instance
    instance = client.get(
  File "/home/sigal/.local/share/virtualenvs/ingest-airflow-rHPaIjXZ/lib/python3.8/site-packages/google/cloud/compute_v1/services/instances/client.py", line 2812, in get
    response = rpc(
  File "/home/sigal/.local/share/virtualenvs/ingest-airflow-rHPaIjXZ/lib/python3.8/site-packages/google/api_core/gapic_v1/method.py", line 113, in __call__
    return wrapped_func(*args, **kwargs)
  File "/home/sigal/.local/share/virtualenvs/ingest-airflow-rHPaIjXZ/lib/python3.8/site-packages/google/api_core/grpc_helpers.py", line 72, in error_remapped_callable
    return callable_(*args, **kwargs)
  File "/home/sigal/.local/share/virtualenvs/ingest-airflow-rHPaIjXZ/lib/python3.8/site-packages/google/cloud/compute_v1/services/instances/transports/rest.py", line 2485, in __call__
    raise core_exceptions.from_http_response(response)
google.api_core.exceptions.BadRequest: 400 GET https://compute.googleapis.com/compute/v1/projects/ai2-israel/zones/us-west1-b/instances/%7B%7B%20params.get('dataset')%20%7D%7D: Invalid value for field 'instance': '{{ params.get('dataset') }}'. Must be a match of regex '[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}'
```

### How to reproduce

```python
with DAG(
    dag_id="blob",
    schedule_interval=None,
    start_date=datetime(2023, 1, 1),
    catchup=False,
    params={
        "dataset": Param(default="test"),
    },
    render_template_as_native_obj=True,
) as dag:
        dataset = "{{ params.get('dataset') }}"
        create_vm_instance = CustomComputeEngineInsertInstanceOperator(
                task_id="create_vm_instance",
                project_id=OUR_PROJECT_ID,
                zone=OUR_LOCATION,
                body={
                "name": dataset,
                "machine_type": f"zones/{OUR_LOCATION}/machineTypes/n1-standard-96",
                "source_machine_image": f"global/machineImages/{OUR_IMAGE}",
                "disks": [
                    {
                        "boot": True,
                        "device_name": dataset,
                        "initialize_params": {"disk_size_gb": "10", "disk_type": f"zones/{OUR_LOCATION}/diskTypes/pd-ssd"},
                    }
                ],
                "network_interfaces": [
                    {
                        "access_configs": [{"name": "External NAT", "network_tier": "PREMIUM"}],
                        "stack_type": "IPV4_ONLY",
                        "subnetwork": f"regions/{OUR_REGION}/subnetworks/default",
                    }
                ],
            }
        )
```

### Operating System

Ubuntu 20.04.6 LTS

### Versions of Apache Airflow Providers

_No response_

### Deployment

Official Apache Airflow Helm Chart

### Deployment details

_No response_

### Anything else

_No response_

### Are you willing to submit PR?

- [X] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)



Discussion:
Thanks for opening your first issue here! Be sure to follow the issue template! If you are willing to raise PR to address this issue please do so, no need to wait for approval.


Resolving patch:
diff --git a/airflow/providers/google/cloud/operators/compute.py b/airflow/providers/google/cloud/operators/compute.py
--- a/airflow/providers/google/cloud/operators/compute.py
+++ b/airflow/providers/google/cloud/operators/compute.py
@@ -127,6 +127,7 @@ class ComputeEngineInsertInstanceOperator(ComputeEngineBaseOperator):
         "gcp_conn_id",
         "api_version",
         "impersonation_chain",
+        "resource_id",
     )
     # [END gce_instance_insert_fields]
 
@@ -306,6 +307,7 @@ class ComputeEngineInsertInstanceFromTemplateOperator(ComputeEngineBaseOperator)
         "gcp_conn_id",
         "api_version",
         "impersonation_chain",
+        "resource_id",
     )
     # [END gce_instance_insert_from_template_fields]
 
@@ -869,6 +871,7 @@ class ComputeEngineInsertInstanceTemplateOperator(ComputeEngineBaseOperator):
         "gcp_conn_id",
         "api_version",
         "impersonation_chain",
+        "resource_id",
     )
     # [END gce_instance_template_insert_fields]
 
@@ -1452,6 +1455,7 @@ class ComputeEngineInsertInstanceGroupManagerOperator(ComputeEngineBaseOperator)
         "gcp_conn_id",
         "api_version",
         "impersonation_chain",
+        "resource_id",
     )
     # [END gce_igm_insert_fields]
 


Test patch:
diff --git a/tests/providers/google/cloud/operators/test_compute.py b/tests/providers/google/cloud/operators/test_compute.py
--- a/tests/providers/google/cloud/operators/test_compute.py
+++ b/tests/providers/google/cloud/operators/test_compute.py
@@ -247,6 +247,41 @@ def test_insert_instance_should_throw_ex_when_missing_resource_id(self, mock_hoo
             op.execute(context=mock.MagicMock())
         mock_hook.assert_not_called()
 
+    @mock.patch(COMPUTE_ENGINE_HOOK_PATH)
+    def test_insert_instance_should_not_throw_ex_when_name_is_templated(self, mock_hook):
+        get_instance_obj_mock = mock.MagicMock()
+        get_instance_obj_mock.__class__ = Instance
+        mock_hook.return_value.get_instance.side_effect = [
+            NotFound("Error message"),
+            get_instance_obj_mock,
+        ]
+        body_with_templated_name = deepcopy(GCE_INSTANCE_BODY_API_CALL)
+        body_with_templated_name["name"] = "{{ execution_date }}"
+        op = ComputeEngineInsertInstanceOperator(
+            project_id=GCP_PROJECT_ID,
+            resource_id=GCE_RESOURCE_ID,
+            body=body_with_templated_name,
+            zone=GCE_ZONE,
+            task_id=TASK_ID,
+            retry=RETRY,
+            timeout=TIMEOUT,
+            metadata=METADATA,
+            gcp_conn_id=GCP_CONN_ID,
+            impersonation_chain=IMPERSONATION_CHAIN,
+        )
+        op.execute(context=mock.MagicMock())
+        mock_hook.assert_called_once_with(
+            api_version=API_VERSION,
+            gcp_conn_id=GCP_CONN_ID,
+            impersonation_chain=IMPERSONATION_CHAIN,
+        )
+        mock_hook.return_value.insert_instance.assert_called_once_with(
+            project_id=GCP_PROJECT_ID,
+            body=body_with_templated_name,
+            zone=GCE_ZONE,
+            request_id=None,
+        )
+
 
 class TestGceInstanceInsertFromTemplate:
     @mock.patch(COMPUTE_ENGINE_HOOK_PATH)
@@ -400,6 +435,42 @@ def test_insert_instance_from_template_should_throw_ex_when_missing_body(self, m
             op.execute(context=mock.MagicMock())
         mock_hook.assert_not_called()
 
+    @mock.patch(COMPUTE_ENGINE_HOOK_PATH)
+    def test_insert_instance_from_template_should_not_throw_ex_when_name_is_templated(self, mock_hook):
+        get_instance_obj_mock = mock.MagicMock()
+        get_instance_obj_mock.__class__ = Instance
+        mock_hook.return_value.get_instance.side_effect = [
+            NotFound("Error message"),
+            get_instance_obj_mock,
+        ]
+        body_with_templated_name = deepcopy(GCP_INSTANCE_BODY_FROM_TEMPLATE)
+        body_with_templated_name["name"] = "{{ execution_date }}"
+        op = ComputeEngineInsertInstanceFromTemplateOperator(
+            project_id=GCP_PROJECT_ID,
+            source_instance_template=SOURCE_INSTANCE_TEMPLATE,
+            body=body_with_templated_name,
+            zone=GCE_ZONE,
+            task_id=TASK_ID,
+            retry=RETRY,
+            timeout=TIMEOUT,
+            metadata=METADATA,
+            gcp_conn_id=GCP_CONN_ID,
+            impersonation_chain=IMPERSONATION_CHAIN,
+        )
+        op.execute(context=mock.MagicMock())
+        mock_hook.assert_called_once_with(
+            api_version=API_VERSION,
+            gcp_conn_id=GCP_CONN_ID,
+            impersonation_chain=IMPERSONATION_CHAIN,
+        )
+        mock_hook.return_value.insert_instance.assert_called_once_with(
+            project_id=GCP_PROJECT_ID,
+            zone=GCE_ZONE,
+            body=body_with_templated_name,
+            source_instance_template=SOURCE_INSTANCE_TEMPLATE,
+            request_id=None,
+        )
+
 
 class TestGceInstanceDelete:
     @mock.patch(COMPUTE_ENGINE_HOOK_PATH)
@@ -962,6 +1033,38 @@ def test_insert_template_should_throw_ex_when_missing_body(self, mock_hook):
             op.execute(context=mock.MagicMock())
         mock_hook.assert_not_called()
 
+    @mock.patch(COMPUTE_ENGINE_HOOK_PATH)
+    def test_insert_template_should_not_throw_ex_when_name_is_templated(self, mock_hook):
+        get_template_obj_mock = mock.MagicMock()
+        get_template_obj_mock.__class__ = InstanceTemplate
+        mock_hook.return_value.get_instance_template.side_effect = [
+            NotFound("Error message"),
+            get_template_obj_mock,
+        ]
+        body_with_templated_name = deepcopy(GCE_INSTANCE_TEMPLATE_BODY_API_CALL)
+        body_with_templated_name["name"] = "{{ execution_date }}"
+        op = ComputeEngineInsertInstanceTemplateOperator(
+            project_id=GCP_PROJECT_ID,
+            body=body_with_templated_name,
+            task_id=TASK_ID,
+            retry=RETRY,
+            timeout=TIMEOUT,
+            metadata=METADATA,
+            gcp_conn_id=GCP_CONN_ID,
+            impersonation_chain=IMPERSONATION_CHAIN,
+        )
+        op.execute(context=mock.MagicMock())
+        mock_hook.assert_called_once_with(
+            api_version=API_VERSION,
+            gcp_conn_id=GCP_CONN_ID,
+            impersonation_chain=IMPERSONATION_CHAIN,
+        )
+        mock_hook.return_value.insert_instance_template.assert_called_once_with(
+            project_id=GCP_PROJECT_ID,
+            body=body_with_templated_name,
+            request_id=None,
+        )
+
 
 class TestGceTemplateDelete:
     @mock.patch(COMPUTE_ENGINE_HOOK_PATH)
@@ -1598,6 +1701,40 @@ def test_insert_igm_should_throw_ex_when_missing_body(self, mock_hook):
             op.execute(context=get_instance_group_manager_obj_mock)
         mock_hook.assert_not_called()
 
+    @mock.patch(COMPUTE_ENGINE_HOOK_PATH)
+    def test_insert_igm_should_not_throw_ex_when_name_is_templated(self, mock_hook):
+        get_instance_group_manager_obj_mock = mock.MagicMock()
+        get_instance_group_manager_obj_mock.__class__ = InstanceGroupManager
+        mock_hook.return_value.get_instance_group_manager.side_effect = [
+            NotFound("Error message"),
+            get_instance_group_manager_obj_mock,
+        ]
+        body_with_templated_name = deepcopy(GCE_INSTANCE_GROUP_MANAGER_BODY_API_CALL)
+        body_with_templated_name["name"] = "{{ execution_date }}"
+        op = ComputeEngineInsertInstanceGroupManagerOperator(
+            project_id=GCP_PROJECT_ID,
+            body=body_with_templated_name,
+            zone=GCE_ZONE,
+            task_id=TASK_ID,
+            retry=RETRY,
+            timeout=TIMEOUT,
+            metadata=METADATA,
+            gcp_conn_id=GCP_CONN_ID,
+            impersonation_chain=IMPERSONATION_CHAIN,
+        )
+        op.execute(context=mock.MagicMock())
+        mock_hook.assert_called_once_with(
+            api_version=API_VERSION,
+            gcp_conn_id=GCP_CONN_ID,
+            impersonation_chain=IMPERSONATION_CHAIN,
+        )
+        mock_hook.return_value.insert_instance_group_manager.assert_called_once_with(
+            project_id=GCP_PROJECT_ID,
+            zone=GCE_ZONE,
+            body=body_with_templated_name,
+            request_id=None,
+        )
+
 
 class TestGceInstanceGroupManagerDelete:
     @mock.patch(COMPUTE_ENGINE_HOOK_PATH)