Floci 中的 AWS Control Tower 本地模拟:Landing Zone、Baseline 与 Control 全流程实战指南
2026/9/20 23:49:53 网站建设 项目流程

【免费下载链接】floci

Light, fluffy, and always free - The AWS Local Emulator alternative

项目地址:https://gitcode.com/gh_mirrors/fl/floci
点击查看免费下载

Floci 是一个本地运行的 AWS 服务模拟器(AWS Local Emulator alternative),本文基于其官方服务文档与源码实现,深入讲解 Control Tower 模块的能力边界与底层原理:landing zone(着陆区)的生命周期管理、baseline(基线)与 enabled control(已启用控制项)的本地仿真,以及各类操作标识符(operation identifier)的账本机制。读完本文,你将掌握如何通过 Floci 提供的 REST 端点驱动 Control Tower 工作流(例如 LZA 的 Prepare 阶段与register-organizational-unit模块),理解每个操作的请求格式、参数校验规则、错误语义与存储行为,并学会通过环境变量调整其行为。

概览:协议、端点与定位

Control Tower 在 Floci 中以REST JSON(AWS 服务模型为 Smithy restJson1)协议实现:

  • 协议:REST JSON
  • 端点:http://localhost:4566

Floci 实现 Control Tower 的目的是支撑本地 Cloud Launchpad 与治理(governance)工作流所需的 landing-zone 与 baseline 操作。从源码结构看,该模块由两个控制器、两个服务与三个模型类组成(见 services/controltower 目录):

  • ControlTowerController:负责 landing zone 与 baseline 的 HTTP 路由;
  • ControlTowerService:实现 landing zone 生命周期、基线目录与启用基线、操作账本;
  • ControlTowerControlController/ControlTowerControlService:负责 enabled control 的启用、列表、更新、重置与操作查询;
  • model/LandingZone.javamodel/EnabledBaseline.javamodel/EnabledControl.java:状态模型;
  • SeededLandingZoneFactory:构造预置(seeded)landing zone 的确定性 manifest。

在路由层面,ControlTowerController 注册在根路径/下,所有操作均为POST。控制器注释里明确说明了两个关键设计:这些单段字面量路径(如/list-landingzones)在 JAX-RS 中优先于 S3 的/{bucket}模板路由,因此无需额外路由接线即可命中;同时,所有 landing zone 的 URI 都把 "landingzone" 拼写为一个单词/create-landingzone也是),这是 AWS Control Tower 服务模型本身的定义,调用时不要写成landing-zone

Landing zone 状态机与预置种子

默认行为:无 landing zone 起步

Floci 的正常运行时初始状态没有任何 landing zoneListLandingZones会返回空列表,直到调用CreateLandingZone创建为止。在 ControlTowerService.listLandingZones 中可以看到,默认(seedLandingZone == false)时直接读取存储区,没有数据就返回空列表。

与之对应,测试环境可以通过floci.services.controltower.seed-landing-zone(环境变量FLOCI_SERVICES_CONTROLTOWER_SEED_LANDING_ZONE)开启预置模式,为依赖旧版 Control Tower 行为的测试保留确定性的种子夹具。开启后,首次读取会懒加载(lazy seed)恰好一个ACTIVE状态的 landing zone——源码注释说明了这一设计动机:LZA(Landing Zone Accelerator)的 Prepare 阶段绝不能观察到空的ListLandingZones结果,因为空列表正是 LZA 的创建路径触发器。

种子 landing zone 的确定性结构

种子数据由SeededLandingZoneFactory生成(见 SeededLandingZoneFactory.java),其 ARN 固定为arn:aws:controltower:{region}:{accountId}:landingzone/FLOCISEEDEDLZ1,版本固定为4.0,状态为ACTIVE,漂移状态为IN_SYNC。生成的 manifest 包含:

  • governedRegions:被治理区域列表(当前区域);
  • organizationStructure:名为Security的安全 OU;
  • centralizedLogging:集中日志(日志桶保留 365 天、访问日志桶保留 3650 天、确定性 KMS 密钥 ARN);
  • config:Config 配置(日志桶 365 天、访问日志桶 3650 天);
  • securityRolesenabled=true且绑定当前账号;
  • accessManagementenabled=true(这是 Identity Center 基线自动启用判断的依据)。

注释中特别提醒:manifest 中的每一个键都是刻意保留的,例如securityRoles会被 LZA 的makeManifestDocumentUPDATE 分支无保护地解引用,缺失会导致 LZAsetup-landing-zone模块崩溃。

创建、更新、删除、重置

CreateLandingZone要求请求体必须包含 JSON 对象manifest与字符串version。版本必须匹配^\\d+\\.\\d+$(即 AWS 的digit.digit形态,小数点两侧至少各一位数字),且长度在 3 到 10 之间;tags 必须是对象且最多 200 个键值对,键 ≤ 128 字符、值必须为 ≤ 256 字符的字符串。若当前区域已存在 landing zone,则返回ConflictException(HTTP 409),错误信息为"Updating or deleting the resource can cause an inconsistent state."。创建成功后返回{ "arn", "operationIdentifier" },其中 ARN 形如arn:aws:controltower:{region}:{accountId}:landingzone/{12位短ID},操作标识符为 UUID。

UpdateLandingZone是一个对账汇聚点(reconciliation sink):它接收 LZA 发来的 manifest 原样存储并返回成功,因此种子数据与 LZA 计算出的配置之间的任何不一致,都会在第一次UpdateLandingZone调用时自愈,而不是报错。该方法接受landingZoneIdentifierversionmanifest与可选的remediationTypes;其中remediationTypes数组被严格约束为恰好一个元素且只能是INHERITANCE_DRIFT(与 AWS 服务模型 min 1/max 1 的定义一致)。更新后会设置latestAvailableVersion=4.0status=ACTIVEdriftStatus=IN_SYNC,并记录一个UPDATE类型的操作。

DeleteLandingZoneResetLandingZone与读取路径不同,刻意不经过"种子优先"解析requireSeededLandingZone):它们必须在 landing zone 缺失时如实报错,而不是重新播种一个。二者都要求landingZoneIdentifier与已存 ARN 精确匹配,否则返回ResourceNotFoundException(HTTP 404)。

按账号与区域隔离

Landing zone 以账号 + 区域为隔离维度:状态存储的键是region,而操作账本(operation ledger)的键是accountId::region。源码注释指出账本按作用域隔离,一个账号无法枚举另一个账号的操作,同时设置了上限防止长驻模拟器无界增长。未知或被淘汰(evicted)的操作标识符一律返回ResourceNotFoundException——Floci 不会为它从未签发过的标识符伪造成功的操作结果。

Baselines:基线目录与启用基线

本地基线目录

ListBaselinesPOST /list-baselines)暴露本地基线目录。从 ControlTowerService.BASELINE_CATALOG 看,目录包含五个固定条目,ID 固定以保证确定性,ARN 按区域限定且账号字段为空(与真实 Control Tower 一致):

名称固定 ID描述
AWSControlTowerBaseline17BSJV3IGJ2QSGA2治理一个 OU 所需的资源
ConfigBaselineFLOCICONFIGBASELINE为组织单元设置 AWS Config 资源
IdentityCenterBaselineLN25R72TTG6IGPTQ设置 IAM Identity Center 访问所需的共享资源
AuditBaselineJ8HX46AHS5MIKQPD为审计账号设置资源
LogArchiveBaseline3WFXIAO9KPBTB5TE为日志归档账号设置资源

源码注释特别指出:只有name是承载业务的关键字段(LZA 在register-organizational-unit模块中按名称做大小写不敏感匹配);id固定仅为保证确定性。

启用基线的校验链

EnableBaselinePOST /enable-baseline)的校验链完整呈现了 AWS 模型约束(见 ControlTowerService.enableBaseline):

  1. baselineIdentifier必须是合法 ARN(^arn:aws[...],长度 ≥ 20);
  2. baselineVersion必须匹配^\\d+(?:\\.\\d+){0,2}$且长度 ≤ 10(模型规定的最多三段数字点分版本),并进一步校验该基线支持的具体版本:ConfigBaseline/IdentityCenterBaseline仅支持1.0AWSControlTowerBaseline支持3.0/4.0/5.0,其他基线只要符合\d+\.\d+形态即可;
  3. targetIdentifier必须是 ARN,且当 Organizations 状态可用时,OU 目标必须指向调用者组织中真实存在的 OU——实现通过OrganizationsService.describeOrganizationalUnit校验(见requireOrganizationalUnitTarget),OU 不存在则返回ResourceNotFoundException
  4. parameters必须是数组,每个元素是包含非空keyvalue的对象;
  5. 同一目标上已启用同一基线时返回ConflictException(HTTP 409)——要变更已有启用关系,必须使用UpdateEnabledBaseline而非再次EnableBaseline

启用成功后,启用基线以region::target::baseline复合键存入controltower-enabled-baselines.json存储区,返回{ "operationIdentifier", "arn" }。另外,当启用的是 Control Tower OU 基线时,服务还会调用OrganizationsService.ensureControlTowerGuardrails对该 OU 执行护栏(guardrail)对账(见reconcileControlTowerGuardrails)。

启用基线的列表、查询与更新

ListEnabledBaselinesPOST /list-enabled-baselines)支持通过filter对象按baselineIdentifiers(最多 5 个 ARN)、targetIdentifiers(最多 5 个)、parentIdentifiers(最多 5 个)、statuses(合法值SUCCEEDED/FAILED/UNDER_CHANGE)、inheritanceDriftStatuses(合法值IN_SYNC/DRIFTED)过滤,并支持maxResults(5–100,默认 100)与nextToken分页;返回结果按 ARN 排序。includeChildren=true时,由于 Floci 不物化子级启用基线,响应只包含父级资源。实现中还会做两件事:迁移历史遗留键(region::target→ 复合键region::target::baseline),以及当种子 landing zone 的accessManagement.enabled=true且 Identity Center 基线尚未显式存储时,合成一个IdentityCenterBaseline(固定 IDFLOCIIDCBASELINE1)返回,模拟真实环境中的自动启用行为。

GetEnabledBaselinePOST /get-enabled-baseline)要求enabledBaselineIdentifier为 ARN,找不到则返回ResourceNotFoundExceptionUpdateEnabledBaseline更新版本与参数,ResetEnabledBaseline记录一次RESET_ENABLED_BASELINE操作并把最新操作标识符写回基线状态。

已启用控制项(Enabled Controls)

Control Tower 的治理控制面由独立的ControlTowerControlService提供,存储于controltower-enabled-controls.json

  • EnableControlPOST /enable-control):校验controlIdentifiertargetIdentifier均为 ARN,parameters为含key/value的对象数组,tags最多 200 个键值对;同一目标上重复启用返回ConflictException。成功后生成arn:aws:controltower:{region}:{accountId}:enabledcontrol/{16位短ID}与 UUID 操作 ID,控制状态为SUCCEEDED、漂移状态为IN_SYNC
  • ListEnabledControlsPOST /list-enabled-controls):支持可选targetIdentifier过滤、filter.controlIdentifiers过滤以及filter.driftStatuses(合法值IN_SYNC/DRIFTED/NOT_CHECKING/UNKNOWN),maxResults1–100、nextToken分页,结果按 ARN 排序。
  • GetEnabledControlPOST /get-enabled-control):按 ARN 查询,返回含parameters的详情。
  • UpdateEnabledControlPOST /update-enabled-control):参数必须与当前配置不同,否则返回ValidationException;若控制处于DRIFTED状态则返回ConflictException"A drifted control must be reset instead of updated."),必须先重置再更新。
  • ResetEnabledControlPOST /reset-enabled-control):用于修复非 SCP 控制的漂移。SCP 类控制(AWS-GR_RESTRICT_ROOT_USER_ACCESS_KEYSAWS-GR_RESTRICT_ROOT_USER)不支持重置,会返回ValidationException(与 AWS 行为一致)。
  • GetControlOperationPOST /get-control-operation):操作标识符必须是 UUID,未知或已淘汰的返回ResourceNotFoundException

全部受支持操作速查表

以下为 Floci Control Tower 模块的完整操作清单(全部为POST,端点前缀http://localhost:4566):

操作方法与路径行为
ListLandingZonesPOST /list-landingzones列出调用者的 landing zone,无则返回空列表
GetLandingZonePOST /get-landingzone按 ARN 返回 landing zone
CreateLandingZonePOST /create-landingzone创建 landing zone 并生成操作标识符
UpdateLandingZonePOST /update-landingzone更新 manifest、版本与修复(remediation)设置
DeleteLandingZonePOST /delete-landingzone删除 landing zone 并记录删除操作
ResetLandingZonePOST /reset-landingzone校验 landing zone 并记录重置操作
GetLandingZoneOperationPOST /get-landingzone-operation读取此前签发的操作
ListLandingZoneOperationsPOST /list-landingzone-operations支持过滤与分页地列出已记录操作
ListBaselinesPOST /list-baselines列出受支持的基线目录
ListEnabledBaselinesPOST /list-enabled-baselines支持过滤与分页地列出已启用基线
GetEnabledBaselinePOST /get-enabled-baseline按 ARN 返回已启用基线
EnableBaselinePOST /enable-baseline在受支持的目标上启用基线
ResetEnabledBaselinePOST /reset-enabled-baseline为已启用基线记录重置操作
UpdateEnabledBaselinePOST /update-enabled-baseline更新版本与参数
GetBaselineOperationPOST /get-baseline-operation读取此前签发的基线操作
EnableControlPOST /enable-control在目标上启用控制,返回已启用控制 ARN 与操作 ID
ListEnabledControlsPOST /list-enabled-controls支持 target/filter 分页地列出已启用控制
GetEnabledControlPOST /get-enabled-control返回已启用控制详情与参数
UpdateEnabledControlPOST /update-enabled-control参数与当前配置不同时更新参数
ResetEnabledControlPOST /reset-enabled-control修复非 SCP 已启用控制并记录重置操作
GetControlOperationPOST /get-control-operation读取此前签发的控制操作

操作语义与账本机制

本地即时完成,保留 AWS 状态契约

Floci 在本地完成 Control Tower 操作而非等待外部控制平面,因此成功受理的操作会立即进入终态SUCCEEDED。以GetLandingZoneOperation为例(见 ControlTowerController.operationDetailsNode),响应会同时填充operationIdentifieroperationTypestatus=SUCCEEDEDstartTimeendTime(均为当前时刻),与 AWS 轮询器(pollers)期望的字段形态一致。

尽管如此,AWS 的状态契约仍被完整保留:已签发的操作标识符是有作用域、被记录、被校验的——缺失的标识符会失败(ResourceNotFoundException),而不是返回凭空捏造的成功。GetBaselineOperation对未知操作标识符同样返回ResourceNotFoundException

操作账本:每账号每区域最多 250 条

landing zone 与基线操作账本(OperationLedger)按accountId::region作用域维护,采用插入有序的LinkedHashMap每个作用域最多保留最近 250 条操作,超出时淘汰最旧条目(见 ControlTowerService.OperationLedger)。控制操作的账本容量同样是 250(见ControlTowerControlService.MAX_OPERATIONS_PER_SCOPE)。已淘汰的标识符与任何未知操作行为一致——返回ResourceNotFoundException。该账本刻意保存在内存中,因为同一流水线运行中的轮询器是唯一消费者,未知 ID 依旧可以返回SUCCEEDED(对 LZA 重启安全)。

ListLandingZoneOperations支持filter.types(合法值DELETE/CREATE/UPDATE/RESET,且要求恰好一个值)与filter.statusesSUCCEEDED/FAILED/IN_PROGRESS)过滤,maxResults为 1–100(默认 100),nextToken是十进制偏移字符串。

操作类型命名与 AWS 对齐

基线操作使用 AWS 官方操作名记录,例如ENABLE_BASELINERESET_ENABLED_BASELINEUPDATE_ENABLED_BASELINE;landing zone 操作为CREATE/UPDATE/DELETE/RESET;控制操作为ENABLE_CONTROL/UPDATE_ENABLED_CONTROL/RESET_ENABLED_CONTROLgetOperationType只接受 UUID 形态的操作标识符(^[a-f0-9]{8}-...),非 UUID 直接返回ValidationException

错误语义与提供方侧失败

Floci 的可确定性请求与状态失败使用 Control Tower 模型化错误:

  • ValidationException(HTTP 400):请求体非 JSON 对象、必填字段缺失或类型错误、版本号格式非法、maxResults越界、nextToken非法、过滤枚举值不合法等;
  • ConflictException(HTTP 409):重复创建 landing zone、同一目标重复启用基线或控制、更新处于DRIFTED状态的控制;
  • ResourceNotFoundException(HTTP 404):读取或变更未知的 landing zone ARN、未知/已淘汰的操作标识符、不存在的目标 OU、不存在的基线 ARN 或已启用资源。

AWS 服务模型同样包含提供方侧失败(InternalServerException、限流 throttling、服务配额失败)——这些是 AWS 因环境原因拒绝工作时的错误。Floci不会在缺乏本地可忠实触发的条件时合成这些失败,这是其"确定性优先"设计的一部分:模拟器只复现你能在本地稳定复现的错误路径。

配置项

Control Tower 模块的配置定义于 EmulatorConfig.ControlTowerServiceConfig 与ControlTowerStorageConfig(第 600-605 行),通过环境变量或 YAML 属性注入:

变量默认值描述
FLOCI_SERVICES_CONTROLTOWER_ENABLEDtrue启用或禁用 Control Tower 服务
FLOCI_SERVICES_CONTROLTOWER_SEED_LANDING_ZONEfalse为夹具(fixture)导向的环境播种确定性的 landing zone
FLOCI_STORAGE_SERVICES_CONTROLTOWER_MODE(继承全局)可选的存储模式覆盖
FLOCI_STORAGE_SERVICES_CONTROLTOWER_FLUSH_INTERVAL_MS5000混合存储(hybrid)模式的刷盘间隔(毫秒)

对应 YAML 形式为floci.services.controltower.enabledfloci.services.controltower.seed-landing-zonefloci.storage.services.controltower.modefloci.storage.services.controltower.flush-interval-ms。存储后端由StorageFactory创建:landing zone 与启用基线分别落在controltower-landing-zones.jsoncontroltower-enabled-baselines.json数据文件中,具体存储介质(内存/文件/混合)由全局存储模式及上述覆盖项决定,flushIntervalMs仅影响混合(hybrid)存储模式的落盘频率。

结合测试理解行为边界

仓库测试(ControlTowerServiceTest 与ControlTowerControllerIntegrationTestControlTowerControlControllerIntegrationTest)为上述行为提供了可验证的约束清单,可作为使用时的行为契约:

  • listLandingZonesAlwaysReturnsExactlyOneSeededLandingZone:种子模式下ListLandingZones恒返回恰好一个种子 landing zone;
  • createLandingZoneStoresManifestAndReturnsCreateOperation/createLandingZoneRejectsSecondLandingZoneAndInvalidManifest:创建成功返回CREATE操作;重复创建或非法 manifest 被拒绝;
  • updateLandingZoneStoresManifestVersionAndRemediationTypesAndReturnsOperationId/updateLandingZoneWithoutRemediationTypesClearsThem/updateLandingZoneRejectsUnknownIdentifier:更新落盘并返回操作 ID,未提供remediationTypes时清空该字段,未知标识符被拒绝;
  • deleteLandingZoneRemovesStoredLandingZoneAndReturnsDeleteOperation/deleteLandingZoneRejectsMissingStoredLandingZone:删除真实移除存储并返回DELETE操作,缺失时返回 404;
  • enableBaselineStoresEnabledBaselineByTargetAndEchoesVersion/enableBaselineTwiceForSameTargetReturnsConflict:同一目标重复启用返回冲突;enableBaselineRejectsMalformedBaselineVersion等测试验证了版本号与 ARN 校验。

如果你在本地运行 Floci 后接入 LZA 或自研治理脚本,建议按上述路径逐项验证,确保与预期语义一致。更完整的 API 字段定义可对照 AWS Control Tower API Reference 进行语义对齐。

小结

Floci 的 Control Tower 模块以"确定性、可本地复现、严格对齐 AWS 状态契约"为设计核心:landing zone 按账号/区域隔离并支持种子化起步;baseline 与 control 提供完整的启用/查询/更新/重置生命周期;所有操作均签发有作用域、有限容量的操作标识符,缺失即失败,绝不伪造成功。结合 services/controltower 源码、配置定义与单元测试,你可以把 Control Tower 治理流程完整地搬进本地开发环境,实现可重复、无云成本的 CI 验证。

【免费下载链接】floci

Light, fluffy, and always free - The AWS Local Emulator alternative

项目地址:https://gitcode.com/gh_mirrors/fl/floci
点击查看免费下载
上一篇:Dash.js 开源项目安装与使用教程
下一篇:WiFi感知革命:RuView如何用无摄像头追踪技术重新定义隐私保护监测

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询