ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

moto 的 AWS Config 支持:基于 ConfigQueryModel 的资源发现与配置查询实战指南

moto 的 AWS Config 支持:基于 ConfigQueryModel 的资源发现与配置查询实战指南 Mock测试【免费下载链接】motoA library that allows you to easily mock out tests based on AWS infrastructure.项目地址https://gitcode.com/gh_mirrors/mo/moto点击查看免费下载导读本文围绕 moto 仓库中 docs/docs/aws_config.rst 这一实验性特性文档展开系统讲解 moto 如何为 AWS Config 提供单元测试能力通过ConfigQueryModel基类查询 moto 内部各资源后端region backend的状态并以 AWS Config 的返回格式不含历史记录回吐给调用方。读完本文你将掌握已启用该能力的资源类型S3、IAM 等的用法、四个核心 boto3 客户端方法list_discovered_resources、list_aggregate_discovered_resources、batch_get_resource_config、batch_aggregate_get_resource_config的调用方式以及如何参照 S3/IAM 的既有实现为 moto 新增一个资源类型的 Config 支持Listing 与 Describing 两条开发路径。一、背景为什么 moto 需要模拟 AWS ConfigAWS Config 是 AWS 的一项服务用于描述 AWS 资源类型并跟踪其随时间的变化配置历史。moto 当前不支持配置历史configuration history的变化处理但模拟了一批对单元测试极有价值的 API 方法。如果你的自动化代码需要对接 AWS Config例如查询当前账户下存在哪些 S3 桶、IAM 角色就可以用 moto 的这套模拟能力在测试中复现生产环境的读取行为。它解决的问题是测试代码中直接调用 AWS Config API而无需真实 AWS 账户与真实资源。从仓库实现看moto 的 Config 后端位于 moto/config/models.py其中RESOURCE_MAP是连接 AWS Config 资源类型与各资源模块查询实现的核心映射RESOURCE_MAP: dict[str, ConfigQueryModel[Any]] { AWS::S3::Bucket: s3_config_query, AWS::S3::AccountPublicAccessBlock: s3_account_public_access_block_query, AWS::IAM::Role: role_config_query, AWS::IAM::Policy: policy_config_query, AWS::SNS::Topic: sns_config_query, }注意文档撰写时仅 S3 与 IAM 两类资源启用了该能力而当前仓库源码已在RESOURCE_MAP中额外接入了 S3 的AWS::S3::AccountPublicAccessBlock与 SNS 的AWS::SNS::Topic说明社区正按文档描述的机制持续扩展。二、工作原理查询所有 moto 后端并按 Config 格式返回moto 的 AWS Config 能力通过以下方式运作检查 moto 内部创建的各类资源的状态以 AWS Config 的返回格式sans history即不含历史记录返回这些数据查询给定资源类型对应的所有 moto backendsregions来聚合数据。这一机制仅对已启用该能力的资源类型生效未注册进RESOURCE_MAP的资源类型不会出现在 Config 查询结果中。2.1 当前已启用的资源类型按原文档说明当前已启用S3全部—— 桶本身以及桶级配置IAMRole、Policy—— 角色与客户管理策略。结合 moto/config/models.py 中的RESOURCE_MAP实际可用的资源类型为AWS::S3::Bucket、AWS::S3::AccountPublicAccessBlock、AWS::IAM::Role、AWS::IAM::Policy、AWS::SNS::Topic。其中 IAM 的资源属于“全局global”资源类型S3 则是“区域资源驻留regional resource residency”的全局资源类型——这一差异在 Listing 实现中有显著体现详见下文。2.2 关键源码ConfigQueryModel 基类原文档提到moto/core/models.py中存在ConfigQueryModel基类实际该基类位于 moto/core/common_models.pymoto/core/models.py重导出了相关类型。其核心职责是跟踪该资源类型的所有后端每个区域一个并声明两个抽象方法list_config_service_resources(...)列出资源get_config_resource(...)获取单个资源配置。两个方法的签名当前仓库版本为def list_config_service_resources( self, account_id: str, partition: str, resource_ids: list[str] | None, resource_name: str | None, limit: int, next_token: str | None, backend_region: str | None None, resource_region: str | None None, aggregator: dict[str, Any] | None None, ) - tuple[list[dict[str, Any]], str | None]: raise NotImplementedError() def get_config_resource( self, account_id: str, partition: str, resource_id: str, resource_name: str | None None, backend_region: str | None None, resource_region: str | None None, ) - dict[str, Any] | None: raise NotImplementedError()基类 docstring 对两个参数的语义有明确约定backend_regionAPI 请求到达的区域用于非聚合non-aggregated查询——实现时须传入请求来源区域resource_region置为Noneresource_region资源实际驻留区域用于聚合aggregated查询——此时backend_region置为None可按Filters中的区域参数过滤aggregator仅当资源具有“非标准”聚合逻辑典型如 IAM时传入绝大多数场景可省略传None。三、给开发者的扩展指南如何新增一个资源类型的 Config 支持原文档将新增能力拆为两部分Listing resources列出资源与Describing resources描述资源。二者有共同的前置条件。3.1 基础组件Base Components在 moto 中启用某个资源类型的 Config 能力至少需要以下四件事一个config.py文件负责导入该资源类型的后端来自该模块的__init__.py在该资源的config.py中实现继承ConfigQueryModel的类并编写该资源类型特有的查询逻辑实例化这个ConfigQueryModel子类例如s3_config_query S3ConfigQuery(s3_backends)在 moto/config/models.py 中导入该实例并更新RESOURCE_MAP建立AWS Config 资源类型 → 查询实例的映射。以 S3 为例可对照查看moto/s3/config.pyS3ConfigQuery(S3ConfigQuery)的实现与s3_config_query实例化moto/config/models.pyRESOURCE_MAP中的AWS::S3::Bucket: s3_config_query注册项。3.2 测试要求Testing原文档强调每个资源类型需要覆盖三个层面的测试以IAM::Policy为例后端查询测试如tests/test_iam/test_iam.py中的test_policy_list_config_discovered_resources验证发现的资源能正确返回。必须使用后端模型方法backend model methods创建资源不能使用 boto以保证测试兼容 moto server 模式需同时覆盖 listing 与单对象获取。config dict 测试如test_policy_config_dict以同样方式不用 boto创建资源的每一种有意义的配置形态逐一查询后端并断言生成的 config dict 符合预期。端到端 boto 客户端测试如test_policy_config_client核心是验证前端与后端逻辑协同工作覆盖list_discovered_resources、list_aggregate_discovered_resources、batch_get_resource_config、batch_aggregate_get_resource_config四个调用。注意聚合方法aggregate的参数首字母大写如Limit非聚合方法参数首字母小写如limit写客户端测试时容易踩坑。从 tests/test_iam/test_iam.py 的test_role_config_client可以看到端到端测试的标准写法先put_configuration_aggregator创建聚合器含AllAwsRegions: True或指定AwsRegions两种形态再断言非聚合查询、非聚合分页、聚合查询按Limitlen(CONFIG_REGIONS)时单个 Role 会在每个聚合区域各返回一条等行为。3.3 Listing列出资源原文档指出 S3 是当前模型实现但 S3 比较特殊它是全局资源类型但资源按区域驻留。对大多数资源类型而言以下两点成立各区域后端regional backends各自持有独立的数据集Config 聚合aggregation可以从任意后端区域拉取数据——moto 假定所有数据属于同一个账户。Listing 能力的实现因资源类型而异但至少要返回一个形如以下的List[Dict][ { type: AWS::The AWS Config data type, name: The name of the resource, id: The ID of the resource, region: The region of the resource -- if global, then you may want to have the calling logic pass in the aggregator region in for the resource region -- or just us-east-1 :P } , ... ]moto 的 Config 代码会将该结构正确格式化为聚合与非聚合两种调用的返回体。原文档建议阅读 moto/core/common_models.py 中ConfigQueryModel.list_config_service_resources的 docstring其中对backend_region/resource_region/aggregator的使用有详细注释。3.3.1 通用实现技巧聚合与非聚合查询应当复用同一套整体逻辑差异仅在于非聚合列出指定资源后端的区域backend_region聚合列出需要跨所有后端列出资源并可通过传入resource_region进行过滤。S3 是一个可直接参考的工作实现moto/s3/config.py。其关键点包括资源 ID 即桶名同时传入resource_ids与resource_name时若二者不一致直接返回空列表通过backend_region or resource_region做区域过滤比较每个桶的region_name分页逻辑基于排序后的桶名列表next_token即为桶名S3 因全局命名唯一而未采用region-item-name分页键。分页的一般性建议分页通常需要能够跨任意区域拉取资源因此应当以region-item-name作为分页键——S3 之所以没这么做是因为 S3 具有全局唯一命名空间。在 moto/iam/config.py 中可以印证这一点IAM 的聚合查询为每个(role/policy, region)组合构造一个内部排序键_id: f{policy.id}{region}再据此排序分页。3.3.2 IAM 的特殊聚合逻辑IAM 是“非标准聚合”的典型代表原文档中aggregator参数即为此设计。由于 IAM 角色/策略创建在 us-east-1AWS 所称“全局区域”但 AWS 会将其在聚合器的每个区域中重复返回。moto 的做法是读取聚合器的account_aggregation_sources或organization_aggregation_source若all_aws_regions为 True 则取全部 Config 可用区域否则取aws_regions列表然后在每个区域下复制该资源并排序分页见 moto/iam/config.py。此外IAM 策略查询会排除 AWS 托管策略通过ARN_PARTITION_REGEX :iam::aws正则过滤以贴近默认配置记录器的includeGlobalResourceTypes行为见 moto/iam/config.py。3.4 Describing Resources描述资源获取单个资源的配置与列出资源有相似之处但实现工作量更大由于资源可配置形态繁多必须确保返回的 Config dict 正确。对大多数资源类型各区域后端持有独立数据聚合可跨任意后端区域拉取且假定同账户。当前实现以 S3 为参照。S3 相当复杂桶的配置方式不同Config 返回的内容就不同例如是否配置了公共访问块PublicAccessBlock会影响supplementaryConfiguration。实现资源配置获取时至少需要资源不存在时返回None资源存在时返回一个形如 AWS Config 返回结果的dict。原文档建议阅读 moto/core/common_models.py 中get_config_resource的 docstring。从 moto/s3/config.py 与 moto/iam/config.py 可以看出统一的后处理模式# 取桶/角色/策略对象不存在则返回 None config_data bucket.to_config_dict() # configuration 字段本身是 JSON 字符串 config_data[configuration] json.dumps(config_data[configuration]) # supplementaryConfiguration 中的非字符串值也要转成 JSON 字符串 for field, value in config_data[supplementaryConfiguration].items(): if not isinstance(value, str): config_data[supplementaryConfiguration][field] json.dumps(value) return config_data即各资源模块在自己的模型类上实现to_config_dict()如 S3 桶的to_config_dict可见于 tests/test_s3/test_s3_config.py 中的验证Config 查询层负责补齐configuration与supplementaryConfiguration的 JSON 序列化约定。3.4.1 聚合获取的入参约定get_config_resource同样区分聚合与非聚合非聚合获取须将backend_region设为请求来源区域、resource_region置None聚合获取则从所有区域后端收集并可按resource_region过滤。boto 的批量接口batch_get_resource_config/batch_aggregate_get_resource_config会对每个资源键分别调用 N 次get_config_resource参见 moto/config/models.py 附近的实现及 moto/config/responses.py 的参数转发。四、实战在单元测试中使用 AWS Config 模拟以下基于仓库测试用例tests/test_s3/test_s3_config.py、tests/test_iam/test_iam.py归纳的用法可直接在 moto 环境中复现。4.1 非聚合查询list_discovered_resourcesimport boto3 from moto import mock_aws mock_aws def test_list_s3_buckets(): # 先创建 S3 资源 s3 boto3.client(s3, region_nameus-east-1) s3.create_bucket(Bucketbucket1) config boto3.client(config, region_nameus-east-1) result config.list_discovered_resources(resourceTypeAWS::S3::Bucket) assert result[resourceIdentifiers][0][resourceType] AWS::S3::Bucket assert result[resourceIdentifiers][0][resourceId] bucket1 # 若资源有名称还会返回 resourceName后端行为moto/config/models.py要点limit默认为DEFAULT_PAGE_SIZE100超过 100 抛InvalidLimitExceptionresource_ids与resource_name不可同时传入抛InvalidResourceParametersresource_ids最多 20 个超出抛TooManyResourceIds。4.2 非聚合批量获取batch_get_resource_configconfig boto3.client(config, region_nameus-east-1) response config.batch_get_resource_config( resourceKeys[ {resourceType: AWS::S3::Bucket, resourceId: bucket1}, ] ) # response[baseConfigurationItems] 中每个条目含 configuration 等字段该方法接收resourceKeys小写k每个 key 由resourceType与resourceId组成对应后端会调用资源类型的get_config_resource返回baseConfigurationItems与unprocessedResourceKeys。4.3 聚合查询put_configuration_aggregator 先行聚合查询必须先创建配置聚合器否则抛NoSuchConfigurationAggregatorException见 moto/config/models.pyconfig boto3.client(config, region_nameus-east-1) config.put_configuration_aggregator( ConfigurationAggregatorNametest_aggregator, AccountAggregationSources[{ AccountIds: [123456789012], AllAwsRegions: True, # 或指定 AwsRegions: [us-east-1, us-west-2] }], ) result config.list_aggregate_discovered_resources( ResourceTypeAWS::IAM::Role, # 注意大写 R ConfigurationAggregatorNametest_aggregator, Limit50, )聚合调用参数首字母大写ResourceType、ConfigurationAggregatorName、Limit、NextToken并支持Filters含Region、ResourceId、ResourceName键进行过滤见 moto/config/responses.py 与 moto/config/models.py。对于 IAM 这类全局资源聚合返回会在聚合器覆盖的每个区域各出现一次AllAwsRegionsTrue时则为全部 Config 可用区域测试test_role_config_client正是据此断言len(agg_result[ResourceIdentifiers]) len(CONFIG_REGIONS)。4.4 聚合批量获取batch_aggregate_get_resource_configresult config.batch_aggregate_get_resource_config( ConfigurationAggregatorNametest_aggregator, ResourceIdentifiers[ {ResourceType: AWS::IAM::Role, ResourceId: AROA...}, ], )对应后端实现在 moto/config/models.py 附近参数同样遵循聚合接口的大写首字母约定。五、实现要点速查关注点非聚合list_discovered / batch_get聚合list_aggregate / batch_aggregate_get参数命名首字母小写resourceType、limit首字母大写ResourceType、Limit区域语义backend_region 请求来源区域backend_regionNoneresource_region过滤资源驻留区域数据来源单个区域后端所有区域后端假定同账户前置条件无需先put_configuration_aggregator全局资源IAMregion 返回global在聚合器覆盖的每个区域重复返回分页键建议—以region-item-name分页S3 因全局唯一命名除外六、延伸阅读原文档docs/docs/aws_config.rst基类与契约moto/core/common_models.pyConfigQueryModelConfig 后端与资源映射moto/config/models.pyRESOURCE_MAP、moto/config/responses.py参考实现moto/s3/config.py、moto/iam/config.py、moto/sns/config.py测试样例tests/test_s3/test_s3_config.py、tests/test_iam/test_iam.py结语moto 对 AWS Config 的支持目前仍是实验性的文档与RESOURCE_MAP的演进表明社区正在逐步扩展资源类型覆盖。对于需要编写对接 AWS Config 的自动化代码的开发者这套机制尤其是聚合查询与批量获取能够在纯本地环境中高度仿真真实行为而ConfigQueryModel的清晰契约也为后续贡献者提供了低门槛的扩展路径——只需完成 Listing 与 Describing 两个方法的实现、注册进RESOURCE_MAP并补齐三层测试即可为 moto 增加新的 Config 资源类型支持。赞分享Mock测试【免费下载链接】motoA library that allows you to easily mock out tests based on AWS infrastructure.项目地址https://gitcode.com/gh_mirrors/mo/moto点击查看免费下载相关推荐MicroTip 项目推荐MicroTip 项目推荐 1. 项目基础介绍和主要编程语言 MicroTip 是一个极简、可访问且超轻量级的 CSS 工具提示库。该项目的主要编程语言是 CS开发工具云原生运维Terraform AWS Provider数据源开发查询AWS资源实战Terraform AWS Provider数据源开发查询AWS资源实战 引言你还在手动查询AWS资源属性吗 在使用Terraform管理AWS基础设施时IaC云原生基础设施Envoy 移除 AWS-LC 支持--configaws-lc-fips 构建配置的废弃与迁移指南Envoy 移除 AWS LC 支持 configaws lc fips 构建配置的废弃与迁移指南 导读 本文基于 Envoy 仓库 behavior_c云原生服务网格网络微服务上一篇如何专业优化游戏性能DLSSTweaks高级配置工具完整指南下一篇Vaul组件性能优化终极指南提升首次内容绘制与交互时间创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表