Repository: PrefectHQ/prefect

Issue:
Variables are not resolved in "deployments" section of prefect.yaml on version 2.12.1
### First check

- [X] I added a descriptive title to this issue.
- [X] I used the GitHub search to find a similar issue and didn't find it.
- [X] I searched the Prefect documentation for this issue.
- [X] I checked that this issue is related to Prefect and not one of its dependencies.

### Bug summary

Implemented deployment with `prefect.yaml` according to the official doc. But the variables are not resolved when called `prefect deploy` and when triggered the quick run of the deployment from UI. Pretty sure the variables are there. 
![image](https://github.com/PrefectHQ/prefect/assets/73450708/8a95d80a-892e-4870-9d9a-a8fa40928eb5)
![image (1)](https://github.com/PrefectHQ/prefect/assets/73450708/1b7ee156-6ce6-4036-be70-2d0fcf8cd72b)
![image (2)](https://github.com/PrefectHQ/prefect/assets/73450708/85c79827-b0be-42b3-8bfa-87809e589023)


### Reproduction

```python3
# Welcome to your prefect.yaml file! You can use this file for storing and managing
# configuration for deploying your flows. We recommend committing this file to source
# control along with your flow code.

# Generic metadata about this project
name: mlops-deployments
prefect-version: 2.12.1

# build section allows you to manage and build docker images
build: null

# push section allows you to manage if and how this project is uploaded to remote locations
push: null

# pull section allows you to provide instructions for cloning this project in remote locations
pull:
- prefect.deployments.steps.git_clone:
    id: clone-step
    repository: https://github.com/jomariya23156/prefect-deployments.git
    branch: master
    # access_token: "{{ prefect.blocks.secret.dev-only-token }}"
- prefect.deployments.steps.pip_install_requirements:
    directory: "{{ clone-step.directory }}"
    requirements_file: requirements.txt
    stream_output: False

# the deployments section allows you to provide configuration for deploying flows
deployments:
- name: hi_mom_over_again
  version: null
  tags: []
  description: "Say Hi Mom!"
  schedule: {}
  entrypoint: all_flows.py:hi_mom_flow
  parameters: {}
  work_pool:
    name: "{{ prefect.variables.monitor_pool_name }}"
    work_queue_name: null
    job_variables: {}
- name: drift_detection_evidently
  version: null
  tags: []
  description: Compute Evidently Reports and Test suites 
  schedule:
    # run every 7 days aka weekly aka once a week
    rrule: 'FREQ=DAILY;INTERVAL=7'
  entrypoint: all_flows.py:detect_drift_flow
  parameters: 
    # set default flow parameters
    model_metadata_file_path: "{{ prefect.variables.current_model_metadata_file }}"
    last_days: 7
    last_n: 500
    evidently_project_name: "production_model_monitor"
    evidently_project_desc: "Dashboard for monitoring production models"
  work_pool:
    name: "{{ prefect.variables.monitor_pool_name }}"
    work_queue_name: null
    job_variables: {}
```


### Error

```python3
Shown in the attached images.
```


### Versions

```Text
Version:             2.12.1
API version:         0.8.4
Python version:      3.9.18
Git commit:          f5eed67c
Built:               Fri, Sep 1, 2023 4:01 PM
OS/Arch:             linux/aarch64
Profile:             default
Server type:         server
```


### Additional context

_No response_


Discussion:
Hi @jomariya23156, thanks for creating your first issue!

I was able to find an older [duplicate issue](https://github.com/PrefectHQ/prefect/issues/10388), as it turns out, and I'm starting to work on this today.

Resolving patch:
diff --git a/src/prefect/cli/deploy.py b/src/prefect/cli/deploy.py
--- a/src/prefect/cli/deploy.py
+++ b/src/prefect/cli/deploy.py
@@ -59,7 +59,10 @@
 from prefect.utilities.callables import parameter_schema
 from prefect.utilities.collections import get_from_dict
 from prefect.utilities.slugify import slugify
-from prefect.utilities.templating import apply_values
+from prefect.utilities.templating import (
+    apply_values,
+    resolve_variables,
+)
 
 
 @app.command()
@@ -307,6 +310,8 @@ async def _run_single_deploy(
     build_steps = deploy_config.get("build", actions.get("build")) or []
     push_steps = deploy_config.get("push", actions.get("push")) or []
 
+    deploy_config = await resolve_variables(deploy_config)
+
     if get_from_dict(deploy_config, "schedule.anchor_date") and not get_from_dict(
         deploy_config, "schedule.interval"
     ):


Test patch:
diff --git a/tests/cli/test_deploy.py b/tests/cli/test_deploy.py
--- a/tests/cli/test_deploy.py
+++ b/tests/cli/test_deploy.py
@@ -4446,6 +4446,84 @@ def test_save_user_inputs_overwrite_rejected_saving_cancelled(self):
         assert config["deployments"][1]["schedule"] is None
         assert config["deployments"][1]["work_pool"]["name"] == "inflatable"
 
+    @pytest.mark.usefixtures("project_dir", "interactive_console")
+    async def test_deploy_resolves_variables_in_deployments_section(
+        self, prefect_client, work_pool
+    ):
+        """
+        Ensure deployments section of prefect.yaml placeholders are resolved
+        """
+        # create variable
+        await prefect_client._client.post(
+            "/variables/", json={"name": "my_work_pool", "value": "test-work-pool"}
+        )
+
+        # add variable to deployments section of prefect.yaml
+        prefect_file = Path("prefect.yaml")
+        with prefect_file.open(mode="r") as f:
+            prefect_config = yaml.safe_load(f)
+
+        prefect_config["deployments"] = [
+            {
+                "name": "test-name",
+                "entrypoint": "flows/hello.py:my_flow",
+                "work_pool": {
+                    "name": "{{ prefect.variables.my_work_pool }}",
+                },
+            }
+        ]
+
+        with prefect_file.open(mode="w") as f:
+            yaml.safe_dump(prefect_config, f)
+
+        # ensure it is there!
+        assert (
+            prefect_config["deployments"][0]["work_pool"]["name"]
+            == "{{ prefect.variables.my_work_pool }}"
+        )
+
+        # run deploy
+        result = await run_sync_in_worker_thread(
+            invoke_and_assert,
+            command="deploy flows/hello.py:my_flow -n test-name",
+            user_input=(
+                # reject schedule
+                "n"
+                + readchar.key.ENTER
+                +
+                # accept saving configuration
+                "y"
+                + readchar.key.ENTER
+                # accept overwrite config
+                + "y"
+                + readchar.key.ENTER
+            ),
+            expected_code=0,
+            expected_output_contains=[
+                "Deployment 'An important name/test-name' successfully created",
+                (
+                    "Would you like to save configuration for this deployment for"
+                    " faster deployments in the future?"
+                ),
+                "Would you like to overwrite",
+                "Deployment configuration saved to prefect.yaml!",
+            ],
+        )
+        assert result.exit_code == 0
+        assert "An important name/test" in result.output
+
+        deployment = await prefect_client.read_deployment_by_name(
+            "An important name/test-name"
+        )
+        assert deployment.name == "test-name"
+        assert deployment.work_pool_name == "test-work-pool"
+
+        # ensure variable is resolved in prefect.yaml
+        with prefect_file.open(mode="r") as f:
+            prefect_config = yaml.safe_load(f)
+
+        assert prefect_config["deployments"][0]["work_pool"]["name"] == "test-work-pool"
+
 
 @pytest.mark.usefixtures("project_dir", "interactive_console", "work_pool")
 class TestDeployWithoutEntrypoint: