快速入门:在 Azure 上使用 Terraform 部署适用于容器的 Defender

容器Microsoft Defender是Microsoft Defender for Cloud中的云工作负荷保护计划,可为 Kubernetes 环境提供安全监视、漏洞评估和威胁检测。 在本快速入门中,你将使用 Terraform 在订阅级别启用 Defender for Containers 计划,并部署一个连接到 Log Analytics 工作区且启用了 Microsoft Defender 安全监视的 Azure Kubernetes 服务 (AKS) 群集。

使用 Terraform 可以定义、预览和部署云基础结构。 使用 Terraform 时,请使用 HCL 语法来创建配置文件。 HCL 语法允许你指定云提供商(如 Azure)和构成云基础结构的元素。 创建配置文件后,可以创建 一个执行计划 ,以便在部署基础结构更改之前预览这些更改。 验证更改后,应用执行计划来部署基础结构。

在这篇文章中,你将学会如何:

Important

该 azurerm_security_center_subscription_pricing 资源为整个 Azure 订阅设置 Defender for Containers 计划,而不只是为本快速入门中创建的 AKS 集群设置。 启用标准层会影响订阅中所有受支持的容器资源,包括其他 AKS 群集和容器注册表,并可以增加Azure帐单。 在将此配置应用于与其他工作负载共享的订阅之前,请先查看Defender for Containers 定价。

Prerequisites

  • 安装和配置Terraform。
  • Terraform 版本 1.5.0 或更高版本。
  • 拥有有效订阅的 Azure 帐户。 如果没有 Azure 帐户,请先创建一个。
  • 已安装 Azure CLI,并已使用 az login 登录。
  • 在目标订阅中创建资源组、Log Analytics 工作区和 AKS 群集的权限(例如,参与者角色)。
  • 在订阅范围内修改Microsoft Defender for Cloud定价计划的权限。 你必须在该订阅中被分配为 安全管理员、所有者或参与者角色之一。 有关详细信息,请参阅Defender for Cloud中的用户角色和权限。

实现 Terraform 代码

注释

本文的示例代码位于 Azure Terraform GitHub 存储库中。 你可以查看包含当前和以前 Terraform 版本的测试结果的日志文件。

请参阅更多 文章和示例代码,了解如何使用 Terraform 管理 Azure 资源。

  1. 创建一个目录来测试示例 Terraform 代码,并将其设置为当前目录。

  2. 创建一个名为 main.tf 文件的文件,并添加以下代码:

terraform {
  required_version = ">= 1.5.0"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 4.0"
    }
  }
}

provider "azurerm" {
  features {}
}

data "azurerm_client_config" "current" {}

locals {
  suffix   = substr(replace(data.azurerm_client_config.current.subscription_id, "-", ""), 0, 6)
  location = "chinanorth3"
}

resource "azurerm_resource_group" "example" {
  name     = "rg-aks-defender-${local.suffix}"
  location = local.location
}

resource "azurerm_log_analytics_workspace" "example" {
  name                = "law-aks-defender-${local.suffix}"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  sku                 = "PerGB2018"
  retention_in_days   = 30
}

resource "azurerm_security_center_subscription_pricing" "containers" {
  tier          = "Standard"
  resource_type = "Containers"

  extension {
    name = "AgentlessVmScanning"
    additional_extension_properties = {
      ExclusionTags = jsonencode([])
    }
  }

  extension {
    name = "ContainerSensor"
    additional_extension_properties = {
      AntiMalwareEnabled    = "True"
      AutoProvisioning      = "True"
      InstallationMethod    = "AKSAddon"
      SecurityGatingEnabled = "True"
    }
  }

  extension {
    name = "AgentlessDiscoveryForKubernetes"
  }

  extension {
    name = "ContainerRegistriesVulnerabilityAssessments"
  }

  extension {
    name = "ContainerIntegrityContribution"
  }
}

resource "azurerm_kubernetes_cluster" "example" {
  name                              = "aks-defender-${local.suffix}"
  location                          = azurerm_resource_group.example.location
  resource_group_name               = azurerm_resource_group.example.name
  dns_prefix                        = "aks-defender-${local.suffix}"
  role_based_access_control_enabled = true
  azure_policy_enabled              = true
  oidc_issuer_enabled               = true

  default_node_pool {
    name       = "system"
    node_count = 1
    vm_size    = "Standard_D2s_v3"

    upgrade_settings {
      drain_timeout_in_minutes      = 0
      max_surge                     = "10%"
      node_soak_duration_in_minutes = 0
    }
  }

  identity {
    type = "SystemAssigned"
  }

  microsoft_defender {
    log_analytics_workspace_id = azurerm_log_analytics_workspace.example.id
  }

  tags = {
    Environment = "Test"
    Purpose     = "DefenderForContainers"
  }

  depends_on = [
    azurerm_security_center_subscription_pricing.containers
  ]
}

output "resource_group_name" {
  value = azurerm_resource_group.example.name
}

output "aks_cluster_name" {
  value = azurerm_kubernetes_cluster.example.name
}

output "log_analytics_workspace_id" {
  value = azurerm_log_analytics_workspace.example.id
}

注释

该配置会在 Containers 定价计划中为“适用于容器的 Defender”启用以下扩展:

  • AgentlessVmScanning:在不在节点上安装代理的情况下对 AKS 节点磁盘执行无代理漏洞扫描。
  • ContainerSensor:将Defender传感器部署到 AKS 节点。 AntiMalwareEnabled、AutoProvisioning、InstallationMethod 和 SecurityGatingEnabled 属性可启用恶意软件防护、传感器的自动预配、通过 AKS 安全配置文件加载项进行安装,以及传感器的安全门控。
  • AgentlessDiscoveryForKubernetes:无需代理即可发现 Kubernetes 群集配置和工作负荷数据。
  • ContainerRegistriesVulnerabilityAssessments:扫描Azure 容器注册表中的容器映像是否存在已知漏洞。
  • ContainerIntegrityContribution:监视正在运行的容器的运行时配置偏移和完整性。

AKS 群集资源还会启用 Azure Policy(azure_policy_enabled)以对群集进行大规模治理、启用用于工作负载标识联合的 OIDC 颁发程序(oidc_issuer_enabled),以及启用 Microsoft Defender 安全配置文件(microsoft_defender),该配置文件会将群集连接到 Log Analytics 工作区以进行安全监控。

初始化 Terraform

运行 terraform init,将 Terraform 部署进行初始化。 此命令下载 Azure 提供程序,以便管理您的 Azure 资源。

terraform init -upgrade

要点:

  • 参数 -upgrade 可将必要的提供程序插件升级到符合配置版本约束的最新版本。

创建Terraform执行计划

运行 terraform plan 以创建执行计划。

terraform plan -out main.tfplan

要点:

  • terraform plan 命令创建执行计划,但不执行它。 相反,它会确定需要执行哪些操作来创建配置文件中指定的配置。 此模式允许你在对实际资源进行任何更改之前验证执行计划是否符合预期。
  • 使用可选 -out 参数可以为计划指定输出文件。 使用 -out 参数可以确保所查看的计划与所应用的计划完全一致。

应用 Terraform 的执行计划

运行 terraform apply 以将执行计划应用到您的云基础架构。

terraform apply main.tfplan

要点:

  • 示例 terraform apply 命令假设你先前运行了 terraform plan -out main.tfplan。
  • 如果为 -out 参数指定了不同的文件名,请在对 terraform apply 的调用中使用该相同文件名。
  • 如果未使用参数 -out ,则无需任何参数即可调用 terraform apply 。

验证结果

  1. 从 Terraform 状态获取资源组名称、AKS 群集名称和Log Analytics工作区 ID。

    resource_group_name=$(terraform output -raw resource_group_name)
    aks_cluster_name=$(terraform output -raw aks_cluster_name)
    log_analytics_workspace_id=$(terraform output -raw log_analytics_workspace_id)
    
  2. 使用 az security pricing show 命令验证 Defender for Containers 计划是否已在订阅级别设置为标准层级。

    az security pricing show -n Containers --query "{name:name, tier:pricingTier}" -o table
    

    输出显示 Containers 具有 Standard 定价层的计划。

  3. 使用 az security pricing show 命令检查计划中已启用的扩展。

    az security pricing show -n Containers --query "extensions[].{name:name, isEnabled:isEnabled}" -o table
    

    输出将列出已启用的 AgentlessVmScanning、ContainerSensor、 ContainerRegistriesVulnerabilityAssessmentsAgentlessDiscoveryForKubernetes和ContainerIntegrityContribution扩展。

  4. 使用 az aks show 命令确认 AKS 群集已启用 Azure Policy、OIDC 颁发者和 Microsoft Defender 安全监控。

    az aks show \
      --resource-group $resource_group_name \
      --name $aks_cluster_name \
      --query "{azurePolicy:addonProfiles.azurepolicy.enabled, oidc:oidcIssuerProfile.enabled, defender:securityProfile.defender}" \
      -o json
    

    输出显示 azurePolicy 和 oidc 已设置为 true,以及一个 defender 对象,其中 securityMonitoring.enabled 已设置为 true,logAnalyticsWorkspaceResourceId 已设置为 Terraform 创建的 Log Analytics 工作区的 ID。

  5. 使用 az monitor log-analytics workspace show 命令确认Log Analytics工作区存在并链接到 AKS 群集。

    az monitor log-analytics workspace show --ids $log_analytics_workspace_id --query "{name:name, provisioningState:provisioningState}" -o table
    

    输出显示工作区名称和provisioningState的Succeeded。

清理资源

Important

该azurerm_security_center_subscription_pricing资源管理整个订阅范围内的 Defender for Containers 计划。 当 Terraform 销毁此资源时,它会将整个订阅的定价层级从 Containers 重置回 Free。 此操作会禁用该订阅中所有 AKS 群集和容器注册表的适用于容器的 Defender 保护及其扩展,而不只是本快速入门中创建的资源。 在继续之前,请确认订阅中没有其他群集或工作负载依赖于 Defender for Containers 保护。

如果不再需要通过 Terraform 创建的资源,请执行以下步骤:

  1. 运行 terraform plan 并指定 destroy 标志。

    terraform plan -destroy -out main.destroy.tfplan
    

    要点:

    • terraform plan 命令创建执行计划,但不执行它。 相反,它会确定需要执行哪些操作来创建配置文件中指定的配置。 此模式允许你在对实际资源进行任何更改之前验证执行计划是否符合预期。
    • 使用可选 -out 参数可以为计划指定输出文件。 使用 -out 参数可以确保所查看的计划与所应用的计划完全一致。
  2. 运行 terraform apply 来应用执行计划。

    terraform apply main.destroy.tfplan
    

解决 Azure 上的 Terraform 问题

解决在 Azure 上使用 Terraform 时的常见问题。

后续步骤