diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 110f710..8b36e73 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -23,3 +23,25 @@ updates:
     labels:
       - "pip"
       - "dependencies"
+
+  # Maintain dependencies for pip
+  - package-ecosystem: "pip"
+    directory: "/code/backend"
+    schedule:
+      interval: "weekly"
+      day: "sunday"
+      time: "10:00"
+    labels:
+      - "pip"
+      - "dependencies"
+
+  # Maintain dependencies for Terraform
+  - package-ecosystem: "terraform"
+    directory: "/code/infra"
+    schedule:
+      interval: "weekly"
+      day: "sunday"
+      time: "10:00"
+    labels:
+      - "terraform"
+      - "dependencies"
diff --git a/.github/workflows/_terraformDestroyTemplate.yml b/.github/workflows/_terraformDestroyTemplate.yml
new file mode 100644
index 0000000..ebeae53
--- /dev/null
+++ b/.github/workflows/_terraformDestroyTemplate.yml
@@ -0,0 +1,96 @@
+name: Terraform Destroy Template
+
+on:
+  workflow_call:
+    inputs:
+      environment:
+        required: true
+        type: string
+        default: "dev"
+        description: "Specifies the environment of the deployment."
+      config:
+        required: true
+        type: string
+        description: "Specifies the configuration folder for the deployment."
+      terraform_version:
+        required: true
+        type: string
+        description: "Specifies the terraform version."
+      node_version:
+        required: true
+        type: number
+        description: "Specifies the node version."
+      working_directory:
+        required: true
+        type: string
+        description: "Specifies the working directory."
+      tenant_id:
+        required: true
+        type: string
+        description: "Specifies the tenant id of the deployment."
+      subscription_id:
+        required: true
+        type: string
+        description: "Specifies the subscription id of the deployment."
+    secrets:
+      CLIENT_ID:
+        required: true
+        description: "Specifies the client id."
+
+permissions:
+  id-token: write
+  contents: read
+
+jobs:
+  deployment:
+    name: Terraform Destroy
+    runs-on: [self-hosted]
+    continue-on-error: false
+    environment: ${{ inputs.environment }}
+    if: github.event_name == 'push' || github.event_name == 'release'
+    concurrency:
+      group: terraform-${{ inputs.config }}-${{ inputs.environment }}
+      cancel-in-progress: false
+
+    env:
+      ARM_TENANT_ID: ${{ inputs.tenant_id }}
+      ARM_SUBSCRIPTION_ID: ${{ inputs.subscription_id }}
+      ARM_CLIENT_ID: ${{ secrets.CLIENT_ID }}
+      ARM_USE_OIDC: true
+
+    steps:
+      # Setup Node
+      - name: Setup Node
+        id: node_setup
+        uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
+        with:
+          node-version: ${{ inputs.node_version }}
+
+      # Setup Terraform
+      - name: Setup Terraform
+        id: terraform_setup
+        uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
+        with:
+          terraform_version: ${{ inputs.terraform_version }}
+          terraform_wrapper: true
+
+      # Check Out Repository
+      - name: Check Out Repository
+        id: checkout_repository
+        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+
+      # Terraform Init
+      - name: Terraform Init
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform init -backend-config=../../config/${CONFIG}/azurerm.tfbackend
+        env:
+          CONFIG: ${{ inputs.config }}
+
+      # Terraform Destroy
+      - name: Terraform Destroy
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform apply -var-file="../../config/${CONFIG}/vars.tfvars" -auto-approve -input=false -destroy
+        env:
+          CONFIG: ${{ inputs.config }}
diff --git a/.github/workflows/_terraformEnvironmentTemplate.yml b/.github/workflows/_terraformEnvironmentTemplate.yml
new file mode 100644
index 0000000..6d6ae41
--- /dev/null
+++ b/.github/workflows/_terraformEnvironmentTemplate.yml
@@ -0,0 +1,238 @@
+name: Terraform Template
+
+on:
+  workflow_call:
+    inputs:
+      environment:
+        required: true
+        type: string
+        description: "Specifies the environment of the deployment."
+      config:
+        required: true
+        type: string
+        description: "Specifies the configuration folder for the deployment."
+      terraform_version:
+        required: true
+        type: string
+        description: "Specifies the terraform version."
+      node_version:
+        required: true
+        type: number
+        description: "Specifies the node version."
+      working_directory:
+        required: true
+        type: string
+        description: "Specifies the working directory."
+      tenant_id:
+        required: true
+        type: string
+        description: "Specifies the tenant id of the deployment."
+      subscription_id:
+        required: true
+        type: string
+        description: "Specifies the subscription id of the deployment."
+    secrets:
+      CLIENT_ID:
+        required: true
+        description: "Specifies the client id."
+
+permissions:
+  id-token: write
+  contents: read
+  pull-requests: write
+
+jobs:
+  lint:
+    name: Terraform Lint
+    runs-on: [ubuntu-latest]
+    continue-on-error: false
+
+    steps:
+      # Setup Terraform
+      - name: Setup Terraform
+        id: terraform_setup
+        uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
+        with:
+          terraform_version: ${{ inputs.terraform_version }}
+          terraform_wrapper: true
+
+      # Check Out Repository
+      - name: Check Out Repository
+        id: checkout_repository
+        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+
+      # Terraform Format
+      - name: Terraform Format
+        id: terraform_format
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform fmt -check -recursive
+
+      # Add Pull Request Comment
+      - name: Add Pull Request Comment
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
+        id: pr_comment
+        if: github.event_name == 'pull_request'
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          script: |
+            const output = `#### Terraform Lint Results
+            * Terraform Version 📎\`${{ inputs.terraform_version }}\`
+            * Working Directory 📂\`${{ inputs.working_directory }}\`
+            * Terraform Format and Style 🖌\`${{ steps.terraform_format.outcome }}\``;
+
+            github.rest.issues.createComment({
+              issue_number: context.issue.number,
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              body: output
+            })
+
+  plan:
+    name: Terraform Plan
+    runs-on: [self-hosted]
+    continue-on-error: false
+    environment: ${{ inputs.environment }}
+    needs: [lint]
+    concurrency:
+      group: terraform-${{ inputs.config }}-${{ inputs.environment }}
+      cancel-in-progress: false
+
+    env:
+      ARM_TENANT_ID: ${{ inputs.tenant_id }}
+      ARM_SUBSCRIPTION_ID: ${{ inputs.subscription_id }}
+      ARM_CLIENT_ID: ${{ secrets.CLIENT_ID }}
+      ARM_USE_OIDC: true
+
+    steps:
+      # Setup Node
+      - name: Setup Node
+        id: node_setup
+        uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
+        with:
+          node-version: ${{ inputs.node_version }}
+
+      # Setup Terraform
+      - name: Setup Terraform
+        id: terraform_setup
+        uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
+        with:
+          terraform_version: ${{ inputs.terraform_version }}
+          terraform_wrapper: true
+
+      # Check Out Repository
+      - name: Check Out Repository
+        id: checkout_repository
+        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+
+      # Terraform Init
+      - name: Terraform Init
+        id: terraform_init
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform init -backend-config=../../config/${CONFIG}/azurerm.tfbackend
+        env:
+          CONFIG: ${{ inputs.config }}
+
+      # Terraform Validate
+      - name: Terraform Validate
+        id: terraform_validate
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform validate
+
+      # Terraform Plan
+      - name: Terraform Plan
+        id: terraform_plan
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform plan -var-file="../../config/${CONFIG}/vars.tfvars" -input=false
+        env:
+          CONFIG: ${{ inputs.config }}
+
+      # Add Pull Request Comment
+      - name: Add Pull Request Comment
+        id: pr_comment
+        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
+        if: github.event_name == 'pull_request'
+        continue-on-error: true
+        env:
+          PLAN: "terraform\n${{ steps.terraform_plan.outputs.stdout }}"
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+          script: |
+            const output = `#### Terraform Validation & Plan Results
+            * Terraform Version 📎\`${{ inputs.terraform_version }}\`
+            * Working Directory 📂\`${{ inputs.working_directory }}\`
+            * Terraform Initialization ⚙️\`${{ steps.terraform_init.outcome }}\`
+            * Terraform Validation 🤖\`${{ steps.terraform_validate.outcome }}\`
+            * Terraform Plan 📖\`${{ steps.terraform_plan.outcome }}\`
+
+            Show Plan
+
+            \`\`\`\n
+            ${process.env.PLAN}
+            \`\`\`
+
+             `;
+
+            github.rest.issues.createComment({
+              issue_number: context.issue.number,
+              owner: context.repo.owner,
+              repo: context.repo.repo,
+              body: output
+            })
+
+  apply:
+    name: Terraform Apply
+    runs-on: [self-hosted]
+    continue-on-error: false
+    environment: ${{ inputs.environment }}
+    # if: github.event_name == 'push' || github.event_name == 'release'
+    needs: [plan]
+    concurrency:
+      group: terraform-${{ inputs.config }}-${{ inputs.environment }}
+      cancel-in-progress: false
+
+    env:
+      ARM_TENANT_ID: ${{ inputs.tenant_id }}
+      ARM_SUBSCRIPTION_ID: ${{ inputs.subscription_id }}
+      ARM_CLIENT_ID: ${{ secrets.CLIENT_ID }}
+      ARM_USE_OIDC: true
+
+    steps:
+      # Setup Node
+      - name: Setup Node
+        id: node_setup
+        uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
+        with:
+          node-version: ${{ inputs.node_version }}
+
+      # Setup Terraform
+      - name: Setup Terraform
+        id: terraform_setup
+        uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
+        with:
+          terraform_version: ${{ inputs.terraform_version }}
+          terraform_wrapper: true
+
+      # Check Out Repository
+      - name: Check Out Repository
+        id: checkout_repository
+        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+
+      # Terraform Init
+      - name: Terraform Init
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform init -backend-config=../../config/${CONFIG}/azurerm.tfbackend
+        env:
+          CONFIG: ${{ inputs.config }}
+
+      # Terraform Apply
+      - name: Terraform Apply
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform apply -var-file="../../config/${CONFIG}/vars.tfvars" -auto-approve -input=false
+        env:
+          CONFIG: ${{ inputs.config }}
diff --git a/.github/workflows/_terraformImportTemplate.yml b/.github/workflows/_terraformImportTemplate.yml
new file mode 100644
index 0000000..128ed02
--- /dev/null
+++ b/.github/workflows/_terraformImportTemplate.yml
@@ -0,0 +1,108 @@
+name: Terraform Import Template
+
+on:
+  workflow_call:
+    inputs:
+      environment:
+        required: true
+        type: string
+        default: "dev"
+        description: "Specifies the environment of the deployment."
+      config:
+        required: true
+        type: string
+        description: "Specifies the configuration folder for the deployment."
+      terraform_version:
+        required: true
+        type: string
+        description: "Specifies the terraform version."
+      node_version:
+        required: true
+        type: number
+        description: "Specifies the node version."
+      working_directory:
+        required: true
+        type: string
+        description: "Specifies the working directory."
+      tenant_id:
+        required: true
+        type: string
+        description: "Specifies the tenant id of the deployment."
+      subscription_id:
+        required: true
+        type: string
+        description: "Specifies the subscription id of the deployment."
+      import_target:
+        required: true
+        type: string
+        description: "Specifies the terraform resource address (e.g., azurerm_resource_group.my_rg)."
+      resource_id:
+        required: true
+        type: string
+        description: "Specifies the resource id to import (e.g., /subscriptions/.../resourceGroups/myResourceGroup)."
+    secrets:
+      CLIENT_ID:
+        required: true
+        description: "Specifies the client id."
+
+permissions:
+  id-token: write
+  contents: read
+  pull-requests: write
+
+jobs:
+  deployment:
+    name: Terraform Import
+    runs-on: [self-hosted]
+    continue-on-error: false
+    environment: ${{ inputs.environment }}
+    # if: github.event_name == 'push' || github.event_name == 'release'
+    concurrency:
+      group: terraform-${{ inputs.config }}-${{ inputs.environment }}
+      cancel-in-progress: false
+
+    env:
+      ARM_TENANT_ID: ${{ inputs.tenant_id }}
+      ARM_SUBSCRIPTION_ID: ${{ inputs.subscription_id }}
+      ARM_CLIENT_ID: ${{ secrets.CLIENT_ID }}
+      ARM_USE_OIDC: true
+
+    steps:
+      # Setup Node
+      - name: Setup Node
+        id: node_setup
+        uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
+        with:
+          node-version: ${{ inputs.node_version }}
+
+      # Setup Terraform
+      - name: Setup Terraform
+        id: terraform_setup
+        uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
+        with:
+          terraform_version: ${{ inputs.terraform_version }}
+          terraform_wrapper: true
+
+      # Check Out Repository
+      - name: Check Out Repository
+        id: checkout_repository
+        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        with:
+          submodules: true
+
+      # Terraform Init
+      - name: Terraform Init
+        id: terraform_init
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform init -backend-config=../../config/${CONFIG}/azurerm.tfbackend
+        env:
+          CONFIG: ${{ inputs.config }}
+
+      # Terraform Import
+      - name: Terraform Import
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform import -var-file="../../config/${CONFIG}/vars.tfvars" -input=false '${{ inputs.import_target }}' '${{ inputs.resource_id }}'
+        env:
+          CONFIG: ${{ inputs.config }}
diff --git a/.github/workflows/_terraformStateUnlockTemplate.yml b/.github/workflows/_terraformStateUnlockTemplate.yml
new file mode 100644
index 0000000..3a0b174
--- /dev/null
+++ b/.github/workflows/_terraformStateUnlockTemplate.yml
@@ -0,0 +1,100 @@
+name: Terraform State Unlock Template
+
+on:
+  workflow_call:
+    inputs:
+      environment:
+        required: true
+        type: string
+        default: "dev"
+        description: "Specifies the environment of the deployment."
+      config:
+        required: true
+        type: string
+        description: "Specifies the configuration folder for the deployment."
+      terraform_version:
+        required: true
+        type: string
+        description: "Specifies the terraform version."
+      node_version:
+        required: true
+        type: number
+        description: "Specifies the node version."
+      working_directory:
+        required: true
+        type: string
+        description: "Specifies the working directory."
+      tenant_id:
+        required: true
+        type: string
+        description: "Specifies the tenant id of the deployment."
+      subscription_id:
+        required: true
+        type: string
+        description: "Specifies the subscription id of the deployment."
+      lock_id:
+        required: true
+        type: string
+        description: "Specifies the lock_id of the state to unlock."
+    secrets:
+      CLIENT_ID:
+        required: true
+        description: "Specifies the client id."
+
+permissions:
+  id-token: write
+  contents: read
+  pull-requests: write
+
+jobs:
+  deployment:
+    name: Terraform Unlock
+    runs-on: [self-hosted]
+    continue-on-error: false
+    environment: ${{ inputs.environment }}
+    concurrency:
+      group: terraform-${{ inputs.config }}-${{ inputs.environment }}
+      cancel-in-progress: false
+
+    env:
+      ARM_TENANT_ID: ${{ inputs.tenant_id }}
+      ARM_SUBSCRIPTION_ID: ${{ inputs.subscription_id }}
+      ARM_CLIENT_ID: ${{ secrets.CLIENT_ID }}
+      ARM_USE_OIDC: true
+
+    steps:
+      # Setup Node
+      - name: Setup Node
+        id: node_setup
+        uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
+        with:
+          node-version: ${{ inputs.node_version }}
+
+      # Setup Terraform
+      - name: Setup Terraform
+        id: terraform_setup
+        uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
+        with:
+          terraform_version: ${{ inputs.terraform_version }}
+          terraform_wrapper: true
+
+      # Check Out Repository
+      - name: Check Out Repository
+        id: checkout_repository
+        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
+        with:
+          submodules: true
+
+      # Terraform Init
+      - name: Terraform Init
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform init -backend-config=../../config/${CONFIG}/azurerm.tfbackend
+        env:
+          CONFIG: ${{ inputs.config }}
+
+      # Terraform State Unlock
+      - name: Unlock State Terraform
+        working-directory: ${{ inputs.working_directory }}
+        run: |
+          terraform force-unlock -force ${{ inputs.lock_id }}
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index b2c95e5..32ce1ff 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -13,12 +13,12 @@ jobs:
     runs-on: ubuntu-latest
 
     steps:
-      # Setup Python 3.11
-      - name: Setup Python 3.11
+      # Setup Python
+      - name: Setup Python
         id: python_setup
         uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
         with:
-          python-version: "3.11"
+          python-version: "3.13"
 
       # Setup Node
       - name: Setup Node
@@ -32,7 +32,7 @@ jobs:
         id: terraform_setup
         uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
         with:
-          terraform_version: "1.12.2"
+          terraform_version: "1.13.4"
           terraform_wrapper: true
 
       # Checkout repository
diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml
new file mode 100644
index 0000000..30d104f
--- /dev/null
+++ b/.github/workflows/terraform.yml
@@ -0,0 +1,47 @@
+name: Infrastructure Deployment
+on:
+  push:
+    branches:
+      - main
+    paths:
+      - "**.tf"
+      - "code/infra/**"
+      - ".github/workflows/terraform.yml"
+
+  pull_request:
+    branches:
+      - main
+    paths:
+      - "**.tf"
+      - "code/infra/**"
+      - ".github/workflows/terraform.yml"
+
+jobs:
+  terraform_dev:
+    uses: ./.github/workflows/_terraformEnvironmentTemplate.yml
+    name: "Dev"
+    with:
+      environment: "dev"
+      config: "dev"
+      terraform_version: "1.13.4"
+      node_version: 24
+      working_directory: "./code/infra"
+      tenant_id: "37963dd4-f4e6-40f8-a7d6-24b97919e452"
+      subscription_id: "1fdab118-1638-419a-8b12-06c9543714a0"
+    secrets:
+      CLIENT_ID: ${{ secrets.CLIENT_ID }}
+
+  terraform_dev_destroy:
+    uses: ./.github/workflows/_terraformDestroyTemplate.yml
+    name: "Dev - Destroy"
+    needs: [terraform_dev]
+    with:
+      environment: "dev"
+      config: "dev"
+      terraform_version: "1.13.4"
+      node_version: 24
+      working_directory: "./code/infra"
+      tenant_id: "37963dd4-f4e6-40f8-a7d6-24b97919e452"
+      subscription_id: "1fdab118-1638-419a-8b12-06c9543714a0"
+    secrets:
+      CLIENT_ID: ${{ secrets.CLIENT_ID }}
diff --git a/.github/workflows/terraformImport.yml b/.github/workflows/terraformImport.yml
new file mode 100644
index 0000000..19641d5
--- /dev/null
+++ b/.github/workflows/terraformImport.yml
@@ -0,0 +1,44 @@
+name: Import Azure Resource into Terraform State
+
+on:
+  workflow_dispatch:
+    inputs:
+      environment:
+        description: "Specifies the environment of the deployment."
+        required: true
+        type: choice
+        default: "dev"
+        options:
+        - "dev"
+      config:
+        description: "Specifies the config of the deployment."
+        required: true
+        type: choice
+        default: "dev"
+        options:
+        - "dev"
+      import_target:
+        required: true
+        type: string
+        description: 'Specifies the terraform resource address (e.g., azurerm_resource_group.my_rg)'
+      resource_id:
+        required: true
+        type: string
+        description: "Specifies the resource id to import (e.g., /subscriptions/.../resourceGroups/myResourceGroup)"
+
+jobs:
+  terraform_import:
+    uses: ./.github/workflows/_terraformImportTemplate.yml
+    name: "Import"
+    with:
+      environment: ${{ inputs.environment }}
+      config: ${{ inputs.config }}
+      terraform_version: "1.13.4"
+      node_version: 24
+      working_directory: "./code/infra"
+      tenant_id: "37963dd4-f4e6-40f8-a7d6-24b97919e452"
+      subscription_id: "1fdab118-1638-419a-8b12-06c9543714a0"
+      import_target: ${{ inputs.import_target }}
+      resource_id: ${{ inputs.resource_id }}
+    secrets:
+      CLIENT_ID: ${{ secrets.CLIENT_ID }}
diff --git a/.github/workflows/terraformStateUnlock.yml b/.github/workflows/terraformStateUnlock.yml
new file mode 100644
index 0000000..dd1dc09
--- /dev/null
+++ b/.github/workflows/terraformStateUnlock.yml
@@ -0,0 +1,39 @@
+name: Unlock Terraform State
+
+on:
+  workflow_dispatch:
+    inputs:
+      environment:
+        description: "Specifies the environment of the deployment."
+        required: true
+        type: choice
+        default: "dev"
+        options:
+        - "dev"
+      config:
+        description: "Specifies the config of the deployment."
+        required: true
+        type: choice
+        default: "dev"
+        options:
+        - "dev"
+      lock_id:
+        description: 'lock_id of the state to unlock'
+        required: true
+        type: string
+
+jobs:
+  terraform_unlock:
+    uses: ./.github/workflows/_terraformStateUnlockTemplate.yml
+    name: "Dev"
+    with:
+      environment: ${{ inputs.environment }}
+      config: ${{ inputs.config }}
+      terraform_version: "1.13.4"
+      node_version: 24
+      working_directory: "./code/infra"
+      tenant_id: "37963dd4-f4e6-40f8-a7d6-24b97919e452"
+      subscription_id: "1fdab118-1638-419a-8b12-06c9543714a0"
+      lock_id: ${{ inputs.lock_id }}
+    secrets:
+      CLIENT_ID: ${{ secrets.CLIENT_ID }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 920b74d..e5353a1 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -13,11 +13,19 @@ repos:
       - id: pretty-format-json
         args: ["--indent", "2", "--autofix", "--no-sort-keys"]
   - repo: https://github.com/PyCQA/isort
-    rev: 6.0.1
+    rev: 7.0.0
     hooks:
       - id: isort
         args: ["--profile", "black", "--filter-files"]
   - repo: https://github.com/psf/black
-    rev: 25.1.0
+    rev: 25.9.0
     hooks:
       - id: black
+  - repo: local
+    hooks:
+      - id: terraform-fmt
+        name: terraform fmt
+        description: runs terraform fmt
+        entry: terraform fmt -recursive
+        language: system
+        pass_filenames: false
diff --git a/code/infra/aiservice.tf b/code/infra/aiservice.tf
new file mode 100644
index 0000000..066f643
--- /dev/null
+++ b/code/infra/aiservice.tf
@@ -0,0 +1,26 @@
+module "ai_service" {
+  source = "github.com/PerfectThymeTech/terraform-azurerm-modules//modules/aiservice?ref=main"
+  providers = {
+    azurerm = azurerm
+    azapi   = azapi
+    time    = time
+  }
+
+  location                                                = var.location_aoai
+  location_private_endpoint                               = var.location
+  resource_group_name                                     = azurerm_resource_group.resource_group.name
+  tags                                                    = var.tags
+  cognitive_account_name                                  = "${local.prefix}-ai001"
+  cognitive_account_kind                                  = "OpenAI"
+  cognitive_account_sku                                   = "S0"
+  cognitive_account_firewall_bypass_azure_services        = false
+  cognitive_account_outbound_network_access_restricted    = true
+  cognitive_account_outbound_network_access_allowed_fqdns = []
+  cognitive_account_local_auth_enabled                    = false
+  cognitive_account_deployments                           = {}
+  diagnostics_configurations                              = local.diagnostics_configurations
+  subnet_id                                               = azapi_resource.subnet_private_endpoints.id
+  connectivity_delay_in_seconds                           = var.connectivity_delay_in_seconds
+  private_dns_zone_id_cognitive_account                   = var.private_dns_zone_id_open_ai
+  customer_managed_key                                    = var.customer_managed_key
+}
diff --git a/code/infra/applicationinsights.tf b/code/infra/applicationinsights.tf
new file mode 100644
index 0000000..9158db1
--- /dev/null
+++ b/code/infra/applicationinsights.tf
@@ -0,0 +1,14 @@
+module "application_insights" {
+  source = "github.com/PerfectThymeTech/terraform-azurerm-modules//modules/applicationinsights?ref=main"
+  providers = {
+    azurerm = azurerm
+  }
+
+  location                                        = var.location
+  resource_group_name                             = azurerm_resource_group.resource_group.name
+  tags                                            = var.tags
+  application_insights_name                       = "${local.prefix}-appi001"
+  application_insights_application_type           = "web"
+  application_insights_log_analytics_workspace_id = var.log_analytics_workspace_id
+  diagnostics_configurations                      = local.diagnostics_configurations
+}
diff --git a/code/infra/communicationservice.tf b/code/infra/communicationservice.tf
new file mode 100644
index 0000000..254f124
--- /dev/null
+++ b/code/infra/communicationservice.tf
@@ -0,0 +1,13 @@
+module "communication_service" {
+  source = "github.com/PerfectThymeTech/terraform-azurerm-modules//modules/communicationservice?ref=main"
+  providers = {
+    azurerm = azurerm
+  }
+
+  location                            = var.location
+  resource_group_name                 = azurerm_resource_group.resource_group.name
+  tags                                = var.tags
+  communication_service_name          = "${local.prefix}-acs001"
+  communication_service_data_location = var.communication_service_data_location
+  diagnostics_configurations          = local.diagnostics_configurations
+}
diff --git a/code/infra/containerapps.tf b/code/infra/containerapps.tf
new file mode 100644
index 0000000..81c444b
--- /dev/null
+++ b/code/infra/containerapps.tf
@@ -0,0 +1,54 @@
+resource "azurerm_container_app_environment" "container_app_environment" {
+  name                = "${local.prefix}-cae001"
+  location            = var.location
+  resource_group_name = azurerm_resource_group.resource_group.name
+  tags                = var.tags
+
+  dapr_application_insights_connection_string = module.application_insights.application_insights_connection_string
+  infrastructure_resource_group_name          = "${local.prefix}-cae001-rg"
+  infrastructure_subnet_id                    = azapi_resource.subnet_container_app.id
+  internal_load_balancer_enabled              = true
+  logs_destination                            = "azure-monitor"
+  mutual_tls_enabled                          = false
+  workload_profile {
+    name                  = "Consumption"
+    workload_profile_type = "Consumption"
+  }
+  # workload_profile {
+  #   name                  = "D4"
+  #   workload_profile_type = "D4"
+  #   minimum_count         = 1
+  #   maximum_count         = 3
+  # }
+  zone_redundancy_enabled = var.zone_redundancy_enabled
+}
+
+resource "azurerm_monitor_diagnostic_setting" "diagnostic_setting_container_app_environment" {
+  for_each = { for index, value in local.diagnostics_configurations :
+    index => {
+      log_analytics_workspace_id = value.log_analytics_workspace_id,
+      storage_account_id         = value.storage_account_id
+    }
+  }
+  name                       = "applicationLogs-${each.key}"
+  target_resource_id         = azurerm_container_app_environment.container_app_environment.id
+  log_analytics_workspace_id = each.value.log_analytics_workspace_id == "" ? null : each.value.log_analytics_workspace_id
+  storage_account_id         = each.value.storage_account_id == "" ? null : each.value.storage_account_id
+
+  dynamic "enabled_log" {
+    iterator = entry
+    for_each = data.azurerm_monitor_diagnostic_categories.diagnostic_categories_container_app_environment.log_category_groups
+    content {
+      category_group = entry.value
+    }
+  }
+
+  dynamic "metric" {
+    iterator = entry
+    for_each = data.azurerm_monitor_diagnostic_categories.diagnostic_categories_container_app_environment.metrics
+    content {
+      category = entry.value
+      enabled  = true
+    }
+  }
+}
diff --git a/code/infra/data.tf b/code/infra/data.tf
new file mode 100644
index 0000000..7513cdf
--- /dev/null
+++ b/code/infra/data.tf
@@ -0,0 +1,27 @@
+data "azurerm_client_config" "current" {}
+
+data "azurerm_virtual_network" "virtual_network" {
+  name                = local.virtual_network.name
+  resource_group_name = local.virtual_network.resource_group_name
+}
+
+data "azurerm_network_security_group" "network_security_group" {
+  name                = local.network_security_group.name
+  resource_group_name = local.network_security_group.resource_group_name
+}
+
+data "azurerm_route_table" "route_table" {
+  name                = local.route_table.name
+  resource_group_name = local.route_table.resource_group_name
+}
+
+data "azurerm_log_analytics_workspace" "log_analytics_workspace" {
+  provider = azurerm.log_analytics
+
+  name                = local.log_analytics_workspace.name
+  resource_group_name = local.log_analytics_workspace.resource_group_name
+}
+
+data "azurerm_monitor_diagnostic_categories" "diagnostic_categories_container_app_environment" {
+  resource_id = azurerm_container_app_environment.container_app_environment.id
+}
diff --git a/code/infra/keyvault.tf b/code/infra/keyvault.tf
new file mode 100644
index 0000000..a46a178
--- /dev/null
+++ b/code/infra/keyvault.tf
@@ -0,0 +1,18 @@
+module "key_vault" {
+  source = "github.com/PerfectThymeTech/terraform-azurerm-modules//modules/keyvault?ref=main"
+  providers = {
+    azurerm = azurerm
+    time    = time
+  }
+
+  location                             = var.location
+  resource_group_name                  = azurerm_resource_group.resource_group.name
+  tags                                 = var.tags
+  key_vault_name                       = "${local.prefix}-kv001"
+  key_vault_sku_name                   = "standard"
+  key_vault_soft_delete_retention_days = 7
+  diagnostics_configurations           = local.diagnostics_configurations
+  subnet_id                            = azapi_resource.subnet_private_endpoints.id
+  connectivity_delay_in_seconds        = var.connectivity_delay_in_seconds
+  private_dns_zone_id_vault            = var.private_dns_zone_id_vault
+}
diff --git a/code/infra/locals.tf b/code/infra/locals.tf
new file mode 100644
index 0000000..9a79fdf
--- /dev/null
+++ b/code/infra/locals.tf
@@ -0,0 +1,41 @@
+locals {
+  # General locals
+  prefix        = "${lower(var.prefix)}-${var.environment}"
+  github_labels = "aca"
+  resource_providers_to_register = [
+    "Microsoft.Authorization",
+    "Microsoft.App",
+    "Microsoft.Insights",
+    "Microsoft.KeyVault",
+    "Microsoft.ManagedIdentity",
+    "Microsoft.Network",
+    "Microsoft.Resources",
+  ]
+
+  # Resource locals
+  virtual_network = {
+    resource_group_name = split("/", var.vnet_id)[4]
+    name                = split("/", var.vnet_id)[8]
+  }
+  network_security_group = {
+    resource_group_name = split("/", var.nsg_id)[4]
+    name                = split("/", var.nsg_id)[8]
+  }
+  route_table = {
+    resource_group_name = split("/", var.route_table_id)[4]
+    name                = split("/", var.route_table_id)[8]
+  }
+  log_analytics_workspace = {
+    subscription_id     = split("/", var.log_analytics_workspace_id)[2]
+    resource_group_name = split("/", var.log_analytics_workspace_id)[4]
+    name                = split("/", var.log_analytics_workspace_id)[8]
+  }
+
+  # Logging locals
+  diagnostics_configurations = [
+    {
+      log_analytics_workspace_id = var.log_analytics_workspace_id
+      storage_account_id         = ""
+    }
+  ]
+}
diff --git a/code/infra/main.tf b/code/infra/main.tf
new file mode 100644
index 0000000..3b2e460
--- /dev/null
+++ b/code/infra/main.tf
@@ -0,0 +1,5 @@
+resource "azurerm_resource_group" "resource_group" {
+  name     = "${local.prefix}-rg"
+  location = var.location
+  tags     = var.tags
+}
diff --git a/code/infra/network.tf b/code/infra/network.tf
new file mode 100644
index 0000000..806b61e
--- /dev/null
+++ b/code/infra/network.tf
@@ -0,0 +1,58 @@
+resource "azapi_resource" "subnet_container_app" {
+  type      = "Microsoft.Network/virtualNetworks/subnets@2024-01-01"
+  name      = "ConAppEnvironmentSubnet"
+  parent_id = data.azurerm_virtual_network.virtual_network.id
+
+  body = {
+    properties = {
+      addressPrefix = var.subnet_cidr_container_app
+      delegations = [
+        {
+          name = "ContainerAppDelegation"
+          properties = {
+            serviceName = "Microsoft.App/environments"
+          }
+        }
+      ]
+      ipAllocations = []
+      networkSecurityGroup = {
+        id = data.azurerm_network_security_group.network_security_group.id
+      }
+      privateEndpointNetworkPolicies    = "Enabled"
+      privateLinkServiceNetworkPolicies = "Enabled"
+      routeTable = {
+        id = data.azurerm_route_table.route_table.id
+      }
+      serviceEndpointPolicies = []
+      serviceEndpoints        = []
+    }
+  }
+}
+
+resource "azapi_resource" "subnet_private_endpoints" {
+  type      = "Microsoft.Network/virtualNetworks/subnets@2024-01-01"
+  name      = "ConAppPrivateEndpointSubnet"
+  parent_id = data.azurerm_virtual_network.virtual_network.id
+
+  body = {
+    properties = {
+      addressPrefix = var.subnet_cidr_private_endpoints
+      delegations   = []
+      ipAllocations = []
+      networkSecurityGroup = {
+        id = data.azurerm_network_security_group.network_security_group.id
+      }
+      privateEndpointNetworkPolicies    = "Enabled"
+      privateLinkServiceNetworkPolicies = "Enabled"
+      routeTable = {
+        id = data.azurerm_route_table.route_table.id
+      }
+      serviceEndpointPolicies = []
+      serviceEndpoints        = []
+    }
+  }
+
+  depends_on = [
+    azapi_resource.subnet_container_app
+  ]
+}
diff --git a/code/infra/providers.tf b/code/infra/providers.tf
new file mode 100644
index 0000000..476903c
--- /dev/null
+++ b/code/infra/providers.tf
@@ -0,0 +1,51 @@
+provider "azurerm" {
+  disable_correlation_request_id  = false
+  environment                     = "public"
+  resource_provider_registrations = "none"
+  resource_providers_to_register  = local.resource_providers_to_register
+  storage_use_azuread             = true
+  use_oidc                        = true
+
+  features {
+    key_vault {
+      recover_soft_deleted_key_vaults   = true
+      recover_soft_deleted_certificates = true
+      recover_soft_deleted_keys         = true
+      recover_soft_deleted_secrets      = true
+    }
+    resource_group {
+      prevent_deletion_if_contains_resources = false
+    }
+  }
+}
+
+provider "azurerm" {
+  alias                           = "log_analytics"
+  disable_correlation_request_id  = false
+  environment                     = "public"
+  resource_provider_registrations = "none"
+  storage_use_azuread             = true
+  subscription_id                 = local.log_analytics_workspace.subscription_id
+  use_oidc                        = true
+
+  features {
+    key_vault {
+      recover_soft_deleted_key_vaults   = true
+      recover_soft_deleted_certificates = true
+      recover_soft_deleted_keys         = true
+      recover_soft_deleted_secrets      = true
+    }
+    resource_group {
+      prevent_deletion_if_contains_resources = false
+    }
+  }
+}
+
+provider "azapi" {
+  default_location               = var.location
+  default_tags                   = var.tags
+  disable_correlation_request_id = false
+  environment                    = "public"
+  skip_provider_registration     = false
+  use_oidc                       = true
+}
diff --git a/code/infra/roleassignments.tf b/code/infra/roleassignments.tf
new file mode 100644
index 0000000..9fe8f7b
--- /dev/null
+++ b/code/infra/roleassignments.tf
@@ -0,0 +1,12 @@
+resource "azurerm_role_assignment" "current_role_assignment_key_vault_secrets_officer" {
+  scope                = module.key_vault.key_vault_id
+  role_definition_name = "Key Vault Secrets Officer"
+  principal_id         = data.azurerm_client_config.current.object_id
+}
+
+# User Assigned Identity
+resource "azurerm_role_assignment" "uai_role_assignment_key_vault_secrets_user" {
+  scope                = module.key_vault.key_vault_id
+  role_definition_name = "Key Vault Secrets User"
+  principal_id         = module.user_assigned_identity.user_assigned_identity_principal_id
+}
diff --git a/code/infra/terraform.tf b/code/infra/terraform.tf
new file mode 100644
index 0000000..e0482b8
--- /dev/null
+++ b/code/infra/terraform.tf
@@ -0,0 +1,27 @@
+terraform {
+  required_version = ">=1.6.0, <2.0.0"
+
+  required_providers {
+    azurerm = {
+      source  = "hashicorp/azurerm"
+      version = "4.18.0"
+    }
+    azapi = {
+      source  = "azure/azapi"
+      version = "2.2.0"
+    }
+    time = {
+      source  = "hashicorp/time"
+      version = "0.12.1"
+    }
+  }
+
+  backend "azurerm" {
+    environment          = "public"
+    resource_group_name  = ""
+    storage_account_name = ""
+    container_name       = ""
+    key                  = ""
+    use_azuread_auth     = true
+  }
+}
diff --git a/code/infra/userassignedidentity.tf b/code/infra/userassignedidentity.tf
new file mode 100644
index 0000000..f28123a
--- /dev/null
+++ b/code/infra/userassignedidentity.tf
@@ -0,0 +1,12 @@
+module "user_assigned_identity" {
+  source = "github.com/PerfectThymeTech/terraform-azurerm-modules//modules/userassignedidentity?ref=main"
+  providers = {
+    azurerm = azurerm
+  }
+
+  location                                              = var.location
+  resource_group_name                                   = azurerm_resource_group.resource_group.name
+  tags                                                  = var.tags
+  user_assigned_identity_name                           = "${local.prefix}-uai001"
+  user_assigned_identity_federated_identity_credentials = {}
+}
diff --git a/code/infra/variables.tf b/code/infra/variables.tf
new file mode 100644
index 0000000..59db072
--- /dev/null
+++ b/code/infra/variables.tf
@@ -0,0 +1,205 @@
+# General variables
+variable "location" {
+  description = "Specifies the location for all Azure resources."
+  type        = string
+  sensitive   = false
+}
+
+variable "location_aoai" {
+  description = "Specifies the location for the Azure Open AI resource."
+  type        = string
+  sensitive   = false
+}
+
+variable "environment" {
+  description = "Specifies the environment of the deployment."
+  type        = string
+  sensitive   = false
+  default     = "dev"
+  validation {
+    condition     = contains(["int", "dev", "tst", "qa", "uat", "prd"], var.environment)
+    error_message = "Please use an allowed value: \"int\", \"dev\", \"tst\", \"qa\", \"uat\" or \"prd\"."
+  }
+}
+
+variable "prefix" {
+  description = "Specifies the prefix for all resources created in this deployment."
+  type        = string
+  sensitive   = false
+  validation {
+    condition     = length(var.prefix) >= 2 && length(var.prefix) <= 10
+    error_message = "Please specify a prefix with between 2 and 10 characters inclusive."
+  }
+}
+
+variable "tags" {
+  description = "Specifies the tags that you want to apply to all resources."
+  type        = map(string)
+  sensitive   = false
+  default     = {}
+}
+
+# Service variables
+variable "container_image_reference" {
+  description = "Specifies the container image reference used in Azure Container Jobs."
+  type        = string
+  sensitive   = true
+  validation {
+    condition     = length(var.container_image_reference) > 2
+    error_message = "Please specify a valid container reference."
+  }
+}
+
+variable "communication_service_data_location" {
+  description = "Specifies the data location for the Communication Service."
+  type        = string
+  sensitive   = false
+  default     = "United States"
+  validation {
+    condition     = contains(["Africa", "Asia Pacific", "Australia", "Brazil", "Canada", "Europe", "France", "Germany", "India", "Japan", "Korea", "Norway", "Switzerland", "UAE", "UK", "usgov", "United States"], var.communication_service_data_location)
+    error_message = "Please specify a valid communication service data location."
+  }
+}
+
+# HA/DR variables
+variable "zone_redundancy_enabled" {
+  description = "Specifies whether zone-redundancy should be enabled for all resources."
+  type        = bool
+  sensitive   = false
+  nullable    = false
+  default     = true
+}
+
+# Logging and monitoring variables
+variable "log_analytics_workspace_id" {
+  description = "Specifies the resource ID of the log analytics workspace used for collecting logs."
+  type        = string
+  sensitive   = false
+  validation {
+    condition     = length(split("/", var.log_analytics_workspace_id)) == 9
+    error_message = "Please specify a valid resource ID."
+  }
+}
+
+# Identity variables
+variable "service_principal_name_terraform_plan" {
+  description = "Specifies the name of the service principal used for the Terraform plan in PRs."
+  type        = string
+  sensitive   = false
+  default     = ""
+  validation {
+    condition     = var.service_principal_name_terraform_plan == "" || length(var.service_principal_name_terraform_plan) >= 2
+    error_message = "Please specify a valid name."
+  }
+}
+
+# Network variables
+variable "vnet_id" {
+  description = "Specifies the resource ID of the Vnet used for the Data Landing Zone."
+  type        = string
+  sensitive   = false
+  validation {
+    condition     = length(split("/", var.vnet_id)) == 9
+    error_message = "Please specify a valid resource ID."
+  }
+}
+
+variable "nsg_id" {
+  description = "Specifies the resource ID of the default network security group for the Azure Function."
+  type        = string
+  sensitive   = false
+  validation {
+    condition     = length(split("/", var.nsg_id)) == 9
+    error_message = "Please specify a valid resource ID."
+  }
+}
+
+variable "route_table_id" {
+  description = "Specifies the resource ID of the default route table for the Azure Function."
+  type        = string
+  sensitive   = false
+  validation {
+    condition     = length(split("/", var.route_table_id)) == 9
+    error_message = "Please specify a valid resource ID."
+  }
+}
+
+variable "subnet_cidr_container_app" {
+  description = "Specifies the subnet cidr range for the container app subnet."
+  type        = string
+  sensitive   = false
+  validation {
+    condition     = length(split("/", var.subnet_cidr_container_app)) == 2
+    error_message = "Please specify a valid subnet cidr range."
+  }
+}
+
+variable "subnet_cidr_private_endpoints" {
+  description = "Specifies the subnet cidr range for private endpoints."
+  type        = string
+  sensitive   = false
+  validation {
+    condition     = length(split("/", var.subnet_cidr_private_endpoints)) == 2
+    error_message = "Please specify a valid subnet cidr range."
+  }
+}
+
+variable "connectivity_delay_in_seconds" {
+  description = "Specifies the delay in seconds after the private endpoint deployment (required for the DNS automation via Policies)."
+  type        = number
+  sensitive   = false
+  nullable    = false
+  default     = 120
+  validation {
+    condition     = var.connectivity_delay_in_seconds >= 0
+    error_message = "Please specify a valid non-negative number."
+  }
+}
+
+# DNS variables
+variable "private_dns_zone_id_vault" {
+  description = "Specifies the resource ID of the private DNS zone for Azure Key Vault. Not required if DNS A-records get created via Azure Policy."
+  type        = string
+  sensitive   = false
+  default     = ""
+  validation {
+    condition     = var.private_dns_zone_id_vault == "" || (length(split("/", var.private_dns_zone_id_vault)) == 9 && endswith(var.private_dns_zone_id_vault, "privatelink.vaultcore.azure.net"))
+    error_message = "Please specify a valid resource ID for the private DNS Zone."
+  }
+}
+
+variable "private_dns_zone_id_open_ai" {
+  description = "Specifies the resource ID of the private DNS zone for Azure Open AI. Not required if DNS A-records get created via Azure Policy."
+  type        = string
+  sensitive   = false
+  default     = ""
+  validation {
+    condition     = var.private_dns_zone_id_open_ai == "" || (length(split("/", var.private_dns_zone_id_open_ai)) == 9 && (endswith(var.private_dns_zone_id_open_ai, "privatelink.openai.azure.com")))
+    error_message = "Please specify a valid resource ID for the private DNS Zone."
+  }
+}
+
+# Customer-managed key variables
+variable "customer_managed_key" {
+  description = "Specifies the customer managed key configurations."
+  type = object({
+    key_vault_id                     = string,
+    key_vault_key_id                 = string,
+    key_vault_key_versionless_id     = string,
+    user_assigned_identity_id        = string,
+    user_assigned_identity_client_id = string,
+  })
+  sensitive = false
+  nullable  = true
+  default   = null
+  validation {
+    condition = alltrue([
+      var.customer_managed_key == null || length(split("/", try(var.customer_managed_key.key_vault_id, ""))) == 9,
+      var.customer_managed_key == null || startswith(try(var.customer_managed_key.key_vault_key_id, ""), "https://"),
+      var.customer_managed_key == null || startswith(try(var.customer_managed_key.key_vault_key_versionless_id, ""), "https://"),
+      var.customer_managed_key == null || length(split("/", try(var.customer_managed_key.user_assigned_identity_id, ""))) == 9,
+      var.customer_managed_key == null || length(try(var.customer_managed_key.user_assigned_identity_client_id, "")) >= 2,
+    ])
+    error_message = "Please specify a valid resource ID."
+  }
+}
diff --git a/config/dev/azurerm.tfbackend b/config/dev/azurerm.tfbackend
new file mode 100644
index 0000000..eb59dbc
--- /dev/null
+++ b/config/dev/azurerm.tfbackend
@@ -0,0 +1,7 @@
+environment          = "public"
+subscription_id      = "e82c5267-9dc4-4f45-ac13-abdd5e130d27"
+resource_group_name  = "rg-terraform"
+storage_account_name = "terraformststg001"
+container_name       = "realtime-agent"
+key                  = "terraform.tfstate"
+use_azuread_auth     = true
diff --git a/config/dev/vars.tfvars b/config/dev/vars.tfvars
new file mode 100644
index 0000000..529110f
--- /dev/null
+++ b/config/dev/vars.tfvars
@@ -0,0 +1,35 @@
+# General variables
+location      = "northeurope"
+location_aoai = "swedencentral"
+environment   = "dev"
+prefix        = "voi-aig"
+tags = {
+  "workload" = "voice-agent"
+}
+
+# Service variables
+container_image_reference           = "todo"
+communication_service_data_location = "Europe"
+
+# HA/DR variables
+zone_redundancy_enabled = false
+
+# Logging and monitoring variables
+log_analytics_workspace_id = "/subscriptions/e82c5267-9dc4-4f45-ac13-abdd5e130d27/resourceGroups/ptt-dev-logging-rg/providers/Microsoft.OperationalInsights/workspaces/ptt-dev-log001"
+
+# Identity variables
+service_principal_name_terraform_plan = ""
+
+# Network variables
+vnet_id                       = "/subscriptions/1fdab118-1638-419a-8b12-06c9543714a0/resourceGroups/ptt-dev-networking-rg/providers/Microsoft.Network/virtualNetworks/spoke-ptt-dev-vnet001"
+nsg_id                        = "/subscriptions/1fdab118-1638-419a-8b12-06c9543714a0/resourceGroups/ptt-dev-networking-rg/providers/Microsoft.Network/networkSecurityGroups/ptt-dev-default-nsg001"
+route_table_id                = "/subscriptions/1fdab118-1638-419a-8b12-06c9543714a0/resourceGroups/ptt-dev-networking-rg/providers/Microsoft.Network/routeTables/ptt-dev-default-rt001"
+subnet_cidr_container_app     = "10.3.1.0/26"
+subnet_cidr_private_endpoints = "10.3.1.64/26"
+
+# DNS variables
+private_dns_zone_id_open_ai = "/subscriptions/e82c5267-9dc4-4f45-ac13-abdd5e130d27/resourceGroups/ptt-dev-privatedns-rg/providers/Microsoft.Network/privateDnsZones/privatelink.openai.azure.com"
+private_dns_zone_id_vault   = "/subscriptions/e82c5267-9dc4-4f45-ac13-abdd5e130d27/resourceGroups/ptt-dev-privatedns-rg/providers/Microsoft.Network/privateDnsZones/privatelink.vaultcore.azure.net"
+
+# Customer-managed key variables
+customer_managed_key = null