azure-terraform-defender

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Azure Terraform — Defender for Cloud Compliance Skill

Azure Terraform — Defender for Cloud 合规技能

Scope

适用范围

This skill applies to all Terraform code using the
azurerm
provider. It encodes controls required to maintain a clean Microsoft Defender for Cloud secure score and avoid security recommendations across compute, storage, networking, identity, databases, containers, and PaaS services.
Reference files — load the relevant one when working on a specific resource type:
TopicFileCovers
Storage Accounts
references/storage.md
azurerm_storage_account
, blob/container, private endpoints
Key Vault
references/keyvault.md
azurerm_key_vault
, keys, secrets, RBAC
Databases
references/databases.md
SQL, PostgreSQL, MySQL Flexible, Cosmos DB
Containers
references/containers.md
AKS, ACR, Defender for Containers
Networking
references/networking.md
NSG, VNet, Firewall, Bastion, DDoS, Private Endpoints
App Service
references/appservice.md
Web apps, Function apps
VMs
references/compute-vms.md
Linux/Windows VMs, disk encryption, backup
Identity & IAM
references/identity.md
Managed identities, RBAC, Defender plans, policy
Monitoring
references/monitoring.md
Log Analytics, diagnostic settings, activity alerts
PaaS (misc)
references/paas-misc.md
Redis, Service Bus, Event Hub, API Mgmt, Automation
Terraform Patterns
references/terraform-patterns.md
Provider config, state, secrets, naming, modules
Full MDC Remediation
references/mdc-full-remediation.md
Complete MDC alert → Terraform fix table

本技能适用于所有使用
azurerm
provider的Terraform代码。它纳入了维持Microsoft Defender for Cloud安全评分达标、避免计算、存储、网络、身份、数据库、容器及PaaS服务触发安全建议所需的控制措施。
参考文件 — 处理特定资源类型时加载对应的参考文件:
主题文件覆盖范围
存储账户
references/storage.md
azurerm_storage_account
、blob/容器、专用终结点
密钥保管库
references/keyvault.md
azurerm_key_vault
、密钥、机密、RBAC
数据库
references/databases.md
SQL、PostgreSQL、MySQL Flexible、Cosmos DB
容器
references/containers.md
AKS、ACR、Defender for Containers
网络
references/networking.md
NSG、VNet、防火墙、Bastion、DDoS、专用终结点
应用服务
references/appservice.md
Web应用、函数应用
虚拟机
references/compute-vms.md
Linux/Windows虚拟机、磁盘加密、备份
身份与IAM
references/identity.md
托管标识、RBAC、Defender计划、策略
监控
references/monitoring.md
Log Analytics、诊断设置、活动警报
PaaS(其他)
references/paas-misc.md
Redis、Service Bus、Event Hub、API管理、自动化
Terraform模式
references/terraform-patterns.md
Provider配置、状态、机密、命名、模块
MDC完整修复指南
references/mdc-full-remediation.md
MDC警报→Terraform修复对照表

Mandatory Defaults (All Resources)

强制默认配置(所有资源)

Apply ALL of the following defaults unless the user explicitly overrides with justification.
除非用户提供合理理由明确覆盖,否则必须应用以下所有默认配置。

Required Tags

必填标签

Every resource must include these tags:
hcl
tags = {
  environment  = var.environment           # dev | staging | prod
  cost-center  = var.cost_center
  owner        = var.owner_email
  managed-by   = "terraform"
  workload     = var.workload_name
  created-date = formatdate("YYYY-MM-DD", timestamp())
}
所有资源必须包含以下标签:
hcl
tags = {
  environment  = var.environment           # dev | staging | prod
  cost-center  = var.cost_center
  owner        = var.owner_email
  managed-by   = "terraform"
  workload     = var.workload_name
  created-date = formatdate("YYYY-MM-DD", timestamp())
}

Managed Identity on Every Resource

所有资源启用托管标识

hcl
identity {
  type = "SystemAssigned"
}
Every resource that calls other Azure services must use a managed identity. Never use service principals with client secrets where managed identity is supported.
hcl
identity {
  type = "SystemAssigned"
}
所有调用其他Azure服务的资源必须使用托管标识。在支持托管标识的场景下,绝不要使用带有客户端密钥的服务主体。

TLS 1.2 Minimum on All Services

所有服务强制最低TLS 1.2版本

Every service that exposes a network endpoint must enforce TLS 1.2 as the minimum version.
所有暴露网络端点的服务必须强制将TLS 1.2设为最低版本。

Private Endpoints for All Data Services

所有数据服务使用专用终结点

In production, all storage, database, messaging, and key management services must be accessed via private endpoints with
public_network_access_enabled = false
.
在生产环境中,所有存储、数据库、消息传递和密钥管理服务必须通过专用终结点访问,且设置
public_network_access_enabled = false

Diagnostic Settings for Every PaaS Resource

所有PaaS资源配置诊断设置

Every PaaS resource must have an
azurerm_monitor_diagnostic_setting
sending logs to a Log Analytics workspace. See
references/monitoring.md
for per-resource log categories.

所有PaaS资源必须配置
azurerm_monitor_diagnostic_setting
,将日志发送至Log Analytics工作区。各资源对应的日志类别请参考
references/monitoring.md

Quick Defaults by Resource Type

按资源类型划分的快速默认配置

Storage (
azurerm_storage_account
) — see
references/storage.md

存储(
azurerm_storage_account
)— 详见
references/storage.md

hcl
https_traffic_only_enabled      = true
min_tls_version                 = "TLS1_2"
allow_nested_items_to_be_public = false
shared_access_key_enabled       = false
cross_tenant_replication_enabled = false
infrastructure_encryption_enabled = true

network_rules {
  default_action = "Deny"
  bypass         = ["AzureServices"]
}

blob_properties {
  delete_retention_policy { days = 30 }
  container_delete_retention_policy { days = 30 }
  versioning_enabled = true
}
hcl
https_traffic_only_enabled      = true
min_tls_version                 = "TLS1_2"
allow_nested_items_to_be_public = false
shared_access_key_enabled       = false
cross_tenant_replication_enabled = false
infrastructure_encryption_enabled = true

network_rules {
  default_action = "Deny"
  bypass         = ["AzureServices"]
}

blob_properties {
  delete_retention_policy { days = 30 }
  container_delete_retention_policy { days = 30 }
  versioning_enabled = true
}

Key Vault (
azurerm_key_vault
) — see
references/keyvault.md

密钥保管库(
azurerm_key_vault
)— 详见
references/keyvault.md

hcl
soft_delete_retention_days = 90
purge_protection_enabled   = true
enable_rbac_authorization  = true

network_acls {
  default_action = "Deny"
  bypass         = ["AzureServices"]
}
hcl
soft_delete_retention_days = 90
purge_protection_enabled   = true
enable_rbac_authorization  = true

network_acls {
  default_action = "Deny"
  bypass         = ["AzureServices"]
}

SQL Server (
azurerm_mssql_server
) — see
references/databases.md

SQL服务器(
azurerm_mssql_server
)— 详见
references/databases.md

hcl
minimum_tls_version           = "1.2"
public_network_access_enabled = false

azuread_administrator {
  login_username              = var.aad_admin_login
  object_id                   = var.aad_admin_object_id
  azuread_authentication_only = true
}
Always add:
azurerm_mssql_server_extended_auditing_policy
+
azurerm_mssql_server_vulnerability_assessment
hcl
minimum_tls_version           = "1.2"
public_network_access_enabled = false

azuread_administrator {
  login_username              = var.aad_admin_login
  object_id                   = var.aad_admin_object_id
  azuread_authentication_only = true
}
Always add:
azurerm_mssql_server_extended_auditing_policy
+
azurerm_mssql_server_vulnerability_assessment

PostgreSQL Flexible (
azurerm_postgresql_flexible_server
) — see
references/databases.md

PostgreSQL Flexible(
azurerm_postgresql_flexible_server
)— 详见
references/databases.md

hcl
geo_redundant_backup_enabled = true

authentication {
  active_directory_auth_enabled = true
  password_auth_enabled         = false
  tenant_id                     = data.azurerm_client_config.current.tenant_id
}
Always add log configuration resources:
log_checkpoints
,
log_connections
,
log_disconnections
,
connection_throttling
.
hcl
geo_redundant_backup_enabled = true

authentication {
  active_directory_auth_enabled = true
  password_auth_enabled         = false
  tenant_id                     = data.azurerm_client_config.current.tenant_id
}
Always add log configuration resources:
log_checkpoints
,
log_connections
,
log_disconnections
,
connection_throttling
.

AKS (
azurerm_kubernetes_cluster
) — see
references/containers.md

AKS(
azurerm_kubernetes_cluster
)— 详见
references/containers.md

hcl
role_based_access_control_enabled = true
local_account_disabled            = true
azure_policy_enabled              = true

azure_active_directory_role_based_access_control {
  managed            = true
  azure_rbac_enabled = true
}

microsoft_defender {
  log_analytics_workspace_id = var.log_analytics_workspace_id
}
hcl
role_based_access_control_enabled = true
local_account_disabled            = true
azure_policy_enabled              = true

azure_active_directory_role_based_access_control {
  managed            = true
  azure_rbac_enabled = true
}

microsoft_defender {
  log_analytics_workspace_id = var.log_analytics_workspace_id
}

App Service / Function App — see
references/appservice.md

应用服务/函数应用 — 详见
references/appservice.md

hcl
https_only = true

site_config {
  minimum_tls_version      = "1.2"
  ftps_state               = "Disabled"
  remote_debugging_enabled = false
}

auth_settings_v2 {
  auth_enabled           = true
  require_authentication = true
}
hcl
https_only = true

site_config {
  minimum_tls_version      = "1.2"
  ftps_state               = "Disabled"
  remote_debugging_enabled = false
}

auth_settings_v2 {
  auth_enabled           = true
  require_authentication = true
}

VMs — see
references/compute-vms.md

虚拟机 — 详见
references/compute-vms.md

hcl
encryption_at_host_enabled      = true
secure_boot_enabled             = true
vtpm_enabled                    = true
disable_password_authentication = true   # Linux only
Never assign a public IP directly to a VM. Use Azure Bastion.
hcl
encryption_at_host_enabled      = true
secure_boot_enabled             = true
vtpm_enabled                    = true
disable_password_authentication = true   # Linux only
Never assign a public IP directly to a VM. Use Azure Bastion.

Redis, Service Bus, Event Hub, Cosmos DB, API Mgmt, Automation — see
references/paas-misc.md

Redis、Service Bus、Event Hub、Cosmos DB、API管理、自动化 — 详见
references/paas-misc.md

Key defaults: disable non-SSL ports, disable local auth, no public network access, TLS 1.2, managed identity, private endpoint.

Key defaults: disable non-SSL ports, disable local auth, no public network access, TLS 1.2, managed identity, private endpoint.

Prohibited Patterns — Reject and Flag These

禁止模式 — 需拒绝并标记以下内容

  1. https_traffic_only_enabled = false
    on any storage account
  2. allow_nested_items_to_be_public = true
    on any storage account
  3. shared_access_key_enabled = true
    on storage accounts used for state or sensitive data
  4. purge_protection_enabled = false
    on any Key Vault
  5. soft_delete_retention_days < 7
    on any Key Vault
  6. enable_rbac_authorization = false
    on Key Vault in production
  7. public_network_access_enabled = true
    on any SQL/PostgreSQL/MySQL/Cosmos DB without explicit CIDR allow-listing AND private endpoint
  8. NSG rules:
    access = "Allow"
    +
    direction = "Inbound"
    +
    source_address_prefix = "*"
    or
    "Internet"
    for ports 22, 3389, 5985, 5986
  9. role_based_access_control_enabled = false
    on any AKS cluster
  10. local_account_disabled = false
    on AKS in production
  11. admin_enabled = true
    on any ACR
  12. Service principals with
    client_secret
    where Azure managed identity is supported
  13. role_definition_name = "Owner"
    in any
    azurerm_role_assignment
    without documented justification
  14. Resources deployed without the required tag set
  15. https_only = false
    on any App Service or Function App
  16. site_config { remote_debugging_enabled = true }
    on any App Service/Function App
  17. site_config { ftps_state = "AllAllowed" }
    on any App Service/Function App
  18. cors { allowed_origins = ["*"] }
    on any App Service
  19. enable_non_ssl_port = true
    on Redis Cache
  20. local_auth_enabled = true
    or
    local_authentication_enabled = true
    on Service Bus/Event Hub
  21. local_authentication_disabled = false
    on Cosmos DB
  22. encrypted = false
    on any
    azurerm_automation_variable_*
  23. encryption_at_host_enabled = false
    on any production VM
  24. Hardcoded secrets or connection strings in Terraform variables without
    sensitive = true
  25. No version constraint on
    azurerm
    provider (must pin to at least
    ~> X.Y
    )

  1. https_traffic_only_enabled = false
    on any storage account
  2. allow_nested_items_to_be_public = true
    on any storage account
  3. shared_access_key_enabled = true
    on storage accounts used for state or sensitive data
  4. purge_protection_enabled = false
    on any Key Vault
  5. soft_delete_retention_days < 7
    on any Key Vault
  6. enable_rbac_authorization = false
    on Key Vault in production
  7. public_network_access_enabled = true
    on any SQL/PostgreSQL/MySQL/Cosmos DB without explicit CIDR allow-listing AND private endpoint
  8. NSG rules:
    access = "Allow"
    +
    direction = "Inbound"
    +
    source_address_prefix = "*"
    or
    "Internet"
    for ports 22, 3389, 5985, 5986
  9. role_based_access_control_enabled = false
    on any AKS cluster
  10. local_account_disabled = false
    on AKS in production
  11. admin_enabled = true
    on any ACR
  12. Service principals with
    client_secret
    where Azure managed identity is supported
  13. role_definition_name = "Owner"
    in any
    azurerm_role_assignment
    without documented justification
  14. Resources deployed without the required tag set
  15. https_only = false
    on any App Service or Function App
  16. site_config { remote_debugging_enabled = true }
    on any App Service/Function App
  17. site_config { ftps_state = "AllAllowed" }
    on any App Service/Function App
  18. cors { allowed_origins = ["*"] }
    on any App Service
  19. enable_non_ssl_port = true
    on Redis Cache
  20. local_auth_enabled = true
    or
    local_authentication_enabled = true
    on Service Bus/Event Hub
  21. local_authentication_disabled = false
    on Cosmos DB
  22. encrypted = false
    on any
    azurerm_automation_variable_*
  23. encryption_at_host_enabled = false
    on any production VM
  24. Hardcoded secrets or connection strings in Terraform variables without
    sensitive = true
  25. No version constraint on
    azurerm
    provider (must pin to at least
    ~> X.Y
    )

Review Checklist

审查检查清单

When reviewing a Terraform plan or module, work through this list:
Storage
  • HTTPS-only, min TLS 1.2, no public blob access, shared key disabled, network deny-all default
  • Soft delete (blob + container), versioning enabled
Key Vault
  • Soft delete ≥ 90 days, purge protection, firewall deny-all, RBAC auth
  • Key and secret expiry dates set; rotation policy configured
  • Diagnostic setting with AuditEvent
SQL / Databases
  • AAD-only admin, auditing policy with 90-day retention, TLS 1.2, no public access
  • Vulnerability assessment enabled; threat detection alert policy
  • PostgreSQL: log settings (checkpoints, connections, disconnections, throttling)
  • Cosmos DB: public access disabled, local auth disabled
Containers
  • AKS: RBAC, Azure AD integration, Defender profile, Azure Policy, local accounts disabled
  • AKS: authorized IP ranges on API server; managed identity
  • ACR: admin user disabled, public access disabled, private endpoint
Networking
  • No wildcard source for management ports (22, 3389, 5985, 5986)
  • DDoS Protection on production VNets
  • NSG flow logs enabled (version 2, 90-day retention, traffic analytics)
  • Azure Bastion deployed; no public IPs on VMs
App Service / Function Apps
  • HTTPS-only, TLS 1.2, FTPS disabled, remote debugging off, auth enabled
  • Managed identity, VNet integration, no CORS wildcard
VMs
  • Encryption at host, Trusted Launch (Secure Boot + vTPM)
  • SSH keys only (Linux), no public IP, MDE extension
  • Backup policy enabled, patch management enabled
PaaS (misc)
  • Redis: non-SSL port disabled, TLS 1.2, private endpoint
  • Service Bus / Event Hub: TLS 1.2, local auth disabled, private endpoint
  • API Mgmt: VNet integration, TLS 1.0/1.1 disabled
  • Automation: all variables encrypted, no public access, managed identity
Monitoring
  • Diagnostic settings on every PaaS resource
  • Subscription activity log forwarded to Log Analytics
  • CIS 5.2.x activity log alerts for policy, NSG, security, SQL firewall changes
  • Log Analytics retention ≥ 365 days
Identity & IAM
  • All Defender plans enabled at subscription level
  • No Owner role assignments without justification
  • Security contact configured in MDC
  • Managed identity on every resource that calls Azure services
Terraform Patterns
  • Provider version pinned (
    ~> X.Y
    )
  • .terraform.lock.hcl
    committed
  • All secrets marked
    sensitive = true
    ; no hardcoded secrets
  • State storage account hardened (HTTPS, TLS 1.2, no public access, no SAS keys)
  • prevent_destroy
    on critical resources (Key Vault, databases, Log Analytics, state storage)
  • Required tags on all resources
When reviewing a Terraform plan or module, work through this list:
Storage
  • HTTPS-only, min TLS 1.2, no public blob access, shared key disabled, network deny-all default
  • Soft delete (blob + container), versioning enabled
Key Vault
  • Soft delete ≥ 90 days, purge protection, firewall deny-all, RBAC auth
  • Key and secret expiry dates set; rotation policy configured
  • Diagnostic setting with AuditEvent
SQL / Databases
  • AAD-only admin, auditing policy with 90-day retention, TLS 1.2, no public access
  • Vulnerability assessment enabled; threat detection alert policy
  • PostgreSQL: log settings (checkpoints, connections, disconnections, throttling)
  • Cosmos DB: public access disabled, local auth disabled
Containers
  • AKS: RBAC, Azure AD integration, Defender profile, Azure Policy, local accounts disabled
  • AKS: authorized IP ranges on API server; managed identity
  • ACR: admin user disabled, public access disabled, private endpoint
Networking
  • No wildcard source for management ports (22, 3389, 5985, 5986)
  • DDoS Protection on production VNets
  • NSG flow logs enabled (version 2, 90-day retention, traffic analytics)
  • Azure Bastion deployed; no public IPs on VMs
App Service / Function Apps
  • HTTPS-only, TLS 1.2, FTPS disabled, remote debugging off, auth enabled
  • Managed identity, VNet integration, no CORS wildcard
VMs
  • Encryption at host, Trusted Launch (Secure Boot + vTPM)
  • SSH keys only (Linux), no public IP, MDE extension
  • Backup policy enabled, patch management enabled
PaaS (misc)
  • Redis: non-SSL port disabled, TLS 1.2, private endpoint
  • Service Bus / Event Hub: TLS 1.2, local auth disabled, private endpoint
  • API Mgmt: VNet integration, TLS 1.0/1.1 disabled
  • Automation: all variables encrypted, no public access, managed identity
Monitoring
  • Diagnostic settings on every PaaS resource
  • Subscription activity log forwarded to Log Analytics
  • CIS 5.2.x activity log alerts for policy, NSG, security, SQL firewall changes
  • Log Analytics retention ≥ 365 days
Identity & IAM
  • All Defender plans enabled at subscription level
  • No Owner role assignments without justification
  • Security contact configured in MDC
  • Managed identity on every resource that calls Azure services
Terraform Patterns
  • Provider version pinned (
    ~> X.Y
    )
  • .terraform.lock.hcl
    committed
  • All secrets marked
    sensitive = true
    ; no hardcoded secrets
  • State storage account hardened (HTTPS, TLS 1.2, no public access, no SAS keys)
  • prevent_destroy
    on critical resources (Key Vault, databases, Log Analytics, state storage)
  • Required tags on all resources