news 2026/10/28 17:31:36

Azure Landing Zones 部署避坑指南:PowerShell 7 与模块版本实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Azure Landing Zones 部署避坑指南:PowerShell 7 与模块版本实战

简介:AzureLandingZones 是一套面向企业级 Azure 架构师与云运维人员的着陆区部署方案,基于微软云采用框架(CAF)对齐的参考架构,并扩展出部署至 Microsoft Azure 政府(MAG)环境的完整说明。资源聚焦多订阅环境下的规模、安全、治理、网络与身份设计,兼顾 IaaS 与 PaaS 场景,可支撑应用迁移与绿地开发。压缩包约 3.02MB,以 PowerShell 脚本为主要载体,用于自动化创建总体云管理结构与治理体系,并附带用户着陆区及其他企业服务模板,便于在既有架构上扩展托管与管理方案。已有 197 人学习关注,适合需要落地合规云环境、复用可重复部署模板的中高级读者参考,可从中获取企业级着陆区的分层部署思路、MAG 适配要点与脚本化落地路径。

1. 从一次订阅初始化翻车说起:Azure Landing Zones 到底装的是什么

第一次在客户环境里跑 Azure Landing Zones 的初始化脚本,我把 PowerShell 窗口一关,以为部署完了,结果第二天打开门户发现管理组层级只建了一半,策略分配全挂在中间层,后面所有订阅都继承不到基线。这套东西不是「装个软件」那么简单,它本质是一组 PowerShell 模块加一套 IaC 模板,把租户根、管理组、订阅、策略、日志归档一次性铺好。装不好最典型的后果就是管理组层级错位、策略继承断链,后面再想改就得手工搬订阅,血泪经验。这篇笔记面向两类人:第一次要在测试租户里跑通 Landing Zones 的开发者,以及已经跑过但被版本和权限坑过的熟手。下面按「环境先列清、再一步步装、最后能验证」的顺序走,PowerShell 版本、模块版本、认证方式都会落到具体命令。

2. 环境准备与版本选择:PowerShell 7 与模块版本的取舍

2.1 为什么不用 Windows PowerShell 5.1 硬跑

Azure Landing Zones 的部署脚本大量依赖Az模块的新版 cmdlet 和并行能力,Windows PowerShell 5.1 虽然能装Az,但在处理大批量管理组和策略定义时容易触发内存与序列化问题,常见表现是跑到一半报Deserialization相关错误。我一般直接上 PowerShell 7.x,当前稳定线是 7.4,LTS 版本对脚本兼容性最好。先确认本机版本:

# 查看当前 PowerShell 版本与运行时 $PSVersionTable.PSVersion $PSVersionTable.PSEdition

PSEdition必须是Core,如果是Desktop说明你还在 5.1 上。版本低于 7.2 的建议升级,因为部分Az子模块已经不再保证对旧运行时的支持。升级方式按平台走:Windows 用winget install Microsoft.PowerShell,macOS 用brew install --cask powershell,Linux 走包管理器装powershell包。装完重开终端再验一次版本,别在旧会话里继续。

2.2 Az 模块的安装方式:整包还是按需

Az是个元模块,整包安装会把几十个子模块全拉下来,首次安装动辄几分钟。Landing Zones 场景实际用到的主要是Az.Accounts、Az.Resources、Az.ManagementPartner、Az.PolicyInsights这几个。我的做法是先整包装一次保证依赖完整,后续再按需更新:

# 安装或更新 Az 元模块,限定当前用户范围避免污染系统级 Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force -AllowClobber # 确认关键子模块版本,Landing Zones 对 Accounts 版本较敏感 Get-Module -ListAvailable Az.Accounts, Az.Resources | Select-Object Name, Version, Path

-Scope CurrentUser避免写系统目录导致权限问题;-AllowClobber是必须的,否则旧版 cmdlet 冲突会直接报错。Az.Accounts建议不低于 2.13,低于这个版本在Connect-AzAccount做租户级认证时偶发令牌刷新失败。装完如果Get-Module列出多个版本,用Import-Module Az.Accounts -RequiredVersion x.y.z锁定,别让脚本自己挑。

2.3 认证方式与所需权限清单

Landing Zones 要在租户根上建管理组,普通订阅贡献者权限不够。常见做法是用一个具备「根管理组用户访问管理员」加「订阅所有者」的服务主体,或者用有全局管理员加计费权限的账号做一次性初始化。服务主体认证更适合可复现:

# 用服务主体登录,凭据从环境变量读取,避免写进脚本 $tenantId = $env:AZ_TENANT_ID $appId = $env:AZ_APP_ID $secret = ConvertTo-SecureString $env:AZ_CLIENT_SECRET -AsPlainText -Force $cred = New-Object System.Management.Automation.PSCredential($appId, $secret) Connect-AzAccount -ServicePrincipal -Tenant $tenantId -Credential $cred Set-AzContext -SubscriptionId $env:AZ_SUBSCRIPTION_ID

-ServicePrincipal走的是应用注册认证,Set-AzContext把默认上下文钉到目标订阅,避免脚本跑到别的订阅上。凭据放环境变量是底线,别硬编码。权限上至少要能在租户根创建管理组、分配策略、创建资源组和存储账户,缺一项都会在中途报AuthorizationFailed,而且报错位置往往在很后面,排查成本高。

3. 拉取 Landing Zones 代码与目录结构落地

3.1 获取模板仓库并锁定版本

Landing Zones 的部署入口在官方模板仓库里,直接克隆主干容易拿到未发布变更。我一般按 release tag 拉,保证可复现:

# 克隆模板仓库并切到指定发布标签 git clone https://github.com/Azure/terraform-azurerm-caf-enterprise-scale.git cd terraform-azurerm-caf-enterprise-scale git checkout v5.0.0 # 确认当前提交与标签一致 git describe --tags --exact-match

这里用的是 Terraform 版模板做示例,如果你走的是 PowerShell 部署路径,对应的是Enterprise-Scale仓库里的Deploy-*脚本目录。git checkout到 tag 而不是分支,是为了避免主干变动导致参数名对不上。git describe输出标签名说明锁定成功,输出报错说明你不在 tag 上,回去重切。

3.2 目录里哪些文件真正要改

模板目录里大部分是模块定义和示例,实际部署只需要动少数几个入口文件。以 Terraform 路径为例,核心是variables.tf里的租户与订阅参数、terraform.tfvars里的环境取值。PowerShell 路径则是Deploy-ALZ.ps1加一个参数文件。先看清结构再动手:

# 列出顶层目录,区分模块、示例与部署入口 ls -1 # 典型输出包含 modules/、examples/、test/、以及部署脚本或 tf 入口

modules/是内部实现,不要改;examples/是参考配置,可以抄参数但别直接跑;真正要改的是根目录的入口脚本和变量文件。我见过有人直接改modules/里的默认值,结果升级模板时全被覆盖,白干。参数文件单独放一个目录,用.gitignore排除,凭据和订阅 ID 都不进版本库。

3.3 参数文件的最小可用配置

不管走哪条路径,参数文件里必须明确四类值:租户 ID、目标订阅 ID、管理组前缀、日志归档区域。少一个都会在部署中途停下来。下面是一个最小参数片段:

# terraform.tfvars 最小示例,字段名以所用模板版本为准 tenant_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" subscription_id_billing = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" root_management_group_name = "alz" default_location = "eastus"

root_management_group_name决定整棵管理组树的根名,改它等于改所有子管理组的继承路径,部署后基本不能改,起名要慎重。default_location影响日志归档和策略里引用的区域,选错会导致部分策略分配指向不存在的区域而失败。参数文件写完后先用模板自带的校验命令跑一遍,别直接上部署。

4. 执行部署:分阶段跑而不是一把梭

4.1 先做 plan 或 what-if,看清要建什么

Landing Zones 一次会创建几十个管理组、上百条策略分配,直接 apply 出问题很难定位。Terraform 路径先plan,PowerShell 路径用-WhatIf:

# Terraform 路径:初始化并生成执行计划 terraform init terraform plan -var-file="terraform.tfvars" -out=alz.tfplan # PowerShell 路径:预演部署动作 ./Deploy-ALZ.ps1 -ParameterFile ./params.json -WhatIf

terraform init会下载 provider,首次较慢;-out把计划存成文件,后面 apply 用同一个文件,保证执行的就是你审过的计划。-WhatIf只打印将要执行的操作不落地,重点看管理组创建顺序和策略分配数量是否符合预期。计划里如果出现删除类操作,先停下来核对,Landing Zones 初始化阶段不该有 destroy。

4.2 分阶段部署:管理组先于策略

一次性 apply 全部资源时,策略分配可能因为管理组还没建完而失败。稳妥做法是分两步:先只建管理组层级,确认继承关系正确,再上策略和日志。Terraform 可以用-target限定范围:

# 第一阶段:只创建管理组层级 terraform apply -target=module.management_groups alz.tfplan # 第二阶段:确认层级后,应用完整计划 terraform apply alz.tfplan

-target是临时手段,只用于分阶段推进,最终仍要以完整计划为准。第一阶段跑完后去门户或 CLI 确认管理组树形结构,根下各层名称和父子关系都对,再进第二阶段。PowerShell 路径对应的是脚本里的-Stage ManagementGroups之类参数,具体名以脚本帮助为准,用Get-Help ./Deploy-ALZ.ps1 -Full查。

4.3 部署过程中的日志与中断处理

部署跑十几分钟很正常,中途断网或令牌过期会留下半成品。脚本一般会写日志文件,先找到它:

# 查找部署日志,通常在脚本同级的 logs 目录 Get-ChildItem -Path . -Filter *.log -Recurse | Sort-Object LastWriteTime -Descending | Select-Object -First 3 FullName, LastWriteTime

日志里重点看Error和Retry两类行。令牌过期表现为AuthenticationFailed或token expired,重新Connect-AzAccount后从失败阶段续跑,不要从头再来,否则已建资源会报已存在。半成品状态最麻烦的是管理组建了一半,这时先手工核对已建层级,再决定是补建还是清理重来。清理时按「策略分配 → 管理组 → 资源组」倒序删,顺序错了会因继承依赖删不掉。

5. 避坑与排查:五条真实踩过的记录

5.1 现象:策略分配报「管理组不存在」

原因通常是部署顺序问题,策略阶段跑在了管理组创建完成之前,或者管理组名称大小写与参数文件不一致。解决:先单独确认管理组存在,Get-AzManagementGroup -GroupName alz,不存在就回到第一阶段补建;存在则核对参数文件里的名称拼写,Landing Zones 对名称大小写敏感,ALZ和alz是两个东西。

5.2 现象:Connect-AzAccount 反复弹认证或直接失败

原因多为Az.Accounts版本过旧,或本机存在多个版本导致加载了错的。解决:Get-Module -ListAvailable Az.Accounts看版本,低于 2.13 就Update-Module Az.Accounts -Force,然后在全新会话里重试。如果仍失败,清掉~/.Azure下的令牌缓存再登录,缓存损坏也会导致认证玄学失败。

5.3 现象:terraform apply 中途报资源已存在

原因是上一次部署中断留下了半成品,或有人在门户里手工建了同名资源。解决:先用terraform state list看状态里有没有该资源,没有就terraform import纳管,别直接删了重建,管理组删了会连带影响子订阅。导入后重新 plan,确认差异只剩预期变更再 apply。

5.4 现象:日志归档存储账户创建失败,报区域不支持

原因是default_location选了一个不提供所需冗余或策略的区域。解决:换成模板文档里列出的受支持区域,常见做法是选主区域加一个配对区域。改参数后只重跑日志模块,别全量重来。区域选错还会导致后续诊断设置指向无效目标,排查时先看存储账户是否真的建出来了。

5.5 现象:部署成功但订阅继承不到策略

原因通常是订阅没挂到正确的管理组下,或策略分配的作用域设在了子层而非根层。解决:Get-AzManagementGroupSubscription确认订阅归属,再用Get-AzPolicyAssignment看分配的作用域字段。作用域应是根管理组或目标层,挂错层就重新分配。这一步是验证阶段的核心,别只看部署脚本返回成功就收工。

6. 装完怎么验证跑通:三层校验与一个习惯

部署脚本返回成功不等于环境可用,我一般走三层校验。第一层看管理组树形结构,确认根、平台层、落地区层、沙箱层都在且父子关系正确:

# 递归列出管理组层级,确认树形结构 Get-AzManagementGroup -GroupName alz -Expand -Recurse | Select-Object Name, DisplayName, ParentName, Children

-Expand -Recurse会把整棵树拉出来,重点核对每个子组的ParentName是否指向预期父级。第二层看策略继承,挑一个落地区订阅,确认基线策略确实生效:

# 查看指定订阅上生效的策略分配 Get-AzPolicyAssignment -Scope "/subscriptions/<sub-id>" | Select-Object Name, PolicyDefinitionId, Scope

Scope字段应指向管理组层级而非订阅本身,说明是继承来的。第三层做一次实际资源部署冒烟测试,在沙箱订阅里建一个资源组加一个存储账户,看是否被策略拦截或自动打标签。三层都过,才算这套 Landing Zones 真的跑通。

下面这张表是我每次验证都会对照的检查项,熟手可以直接拿去当清单:

检查层检查对象通过标准常用命令
结构层管理组树根与各层父子关系正确Get-AzManagementGroup -Expand -Recurse
策略层策略分配作用域在管理组层,订阅可继承Get-AzPolicyAssignment -Scope
冒烟层沙箱资源可创建且符合基线约束门户或New-AzResourceGroup

有个细节容易被忽略:验证要在部署完成后的新会话里做,旧会话的上下文缓存可能让你看到过期结果。我吃过一次亏,旧窗口里查管理组显示正常,新开窗口发现少了一层,原因是部署中断后缓存没刷新。从那以后我每次验证都强制新开一个 PowerShell 会话,先Disconnect-AzAccount再重连,然后才跑上面三层检查。这个习惯看着笨,但省下的排查时间远超那几十秒。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 17:31:28

Redis quicklist:高效列表存储的设计与优化

1. 为什么Redis需要quicklist&#xff1f;在Redis 3.2版本之前&#xff0c;列表(List)类型有两种底层实现&#xff1a;当元素较少时使用ziplist&#xff08;压缩列表&#xff09;&#xff0c;元素较多时转为linkedlist&#xff08;双向链表&#xff09;。这种设计在实践过程中暴…

作者头像 李华
网站建设 2026/10/28 17:30:32

HackRF One在Windows 10/11下的稳定驱动与libhackrf构建指南

简介&#xff1a;本资源是专为x64 Windows平台定制的libhackrf开发库&#xff0c;面向使用HackRF One软件定义无线电&#xff08;SDR&#xff09;设备的C开发者&#xff0c;解决在VS2022环境下快速集成与调用SDR硬件的核心问题。压缩包共5个文件&#xff0c;含3个关键DLL&#…

作者头像 李华
网站建设 2026/10/28 17:29:59

Visual Studio IntelliSense失效排查与优化指南

1. IntelliSense功能失效的常见表现与影响范围Visual Studio的IntelliSense功能出现异常时&#xff0c;通常表现为以下几种典型症状&#xff1a;代码补全列表完全不弹出补全建议出现明显延迟&#xff08;超过3秒&#xff09;只能显示基础语法提示而缺失类成员和方法提示错误地标…

作者头像 李华
网站建设 2026/10/28 17:29:59

微信小程序农产品销售系统:Express+MySQL完整源码实战

简介&#xff1a;本资源是一套完整的微信小程序毕业设计项目源码&#xff0c;面向计算机专业本科生及前端/全栈初学者&#xff0c;解决农产品线上销售平台从需求分析到部署落地的全流程实践问题。压缩包含1197个文件&#xff0c;总大小33.22MB&#xff0c;涵盖127个Java后端业务…

作者头像 李华
网站建设 2026/10/28 17:29:41

Modbus RTU字节序与字序:16/32位数据解析排查指南

1. 同一条 Modbus RTU 报文读出四个不同的数&#xff1a;问题到底出在哪先说一个几乎所有做过 Modbus RTU 采集的人都遇到过的场景&#xff1a;串口助手抓到的报文清清楚楚&#xff0c;功能码 0x03&#xff0c;返回 4 个字节&#xff0c;拼起来是个数&#xff1b;可这个数跟设备…

作者头像 李华
网站建设 2026/10/28 17:29:39

VMware虚拟机去虚拟化实战:硬件标识替换与防检测参数配置

简介&#xff1a;这份文档面向需要在VMware虚拟机中规避鲁大师等软件虚拟化检测的用户&#xff0c;聚焦虚拟机去虚拟化这一进阶操作场景&#xff0c;适合具备一定虚拟机使用经验、希望让虚拟环境更接近真实硬件的读者参考。资源包共1个doc文件&#xff0c;压缩后约76KB&#xf…

作者头像 李华