Skip to content

fix(context): resolve AWS::Partition and AWS::URLSuffix in every region - #4980

Merged
kddejong merged 1 commit into
aws-cloudformation:mainfrom
hoganbr-amzn:fix/partition-url-suffix-table
Nov 3, 2026
Merged

kddejong merged 1 commit into
aws-cloudformation:mainfrom
hoganbr-amzn:fix/partition-url-suffix-table

Conversation

@hoganbr-amzn

@hoganbr-amzn hoganbr-amzn commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Issue #, if available: Fixes #4979

Description of changes:

This PR is stacked on #4976 and #4978 and shows their commits until they merge; the change here is the last commit. The reason is under Why this stacks below.

Three copies of the region-to-partition mapping exist and disagree:

Location Partitions it knows
context/context.py _get_partition (pseudo-parameter values used when resolving functions) aws, aws-us-gov, aws-cn
template/transforms/_language_extensions.py (Fn::ForEach refs) aws, aws-us-gov, aws-cn
E3716 FunctionLayerArnLength._get_partition more partitions, but maps eusc-* to aws-iso-f and us-isof-* to aws-iso

REGIONS already includes regions from every partition, so linting for a region of any other partition, for example eusc-de-east-1, resolves AWS::Partition to aws and AWS::URLSuffix to amazonaws.com.

This adds one table, PARTITIONS in helpers.py, with get_partition(region) and get_url_suffix(region), and uses it in all three places. The region patterns and DNS suffixes match each partition's regionRegex and dnsSuffix in botocore's endpoints.json. An unrecognised region falls back to aws / amazonaws.com, as today.

What changes for users. Nothing in commercial, GovCloud and China regions. In regions of the other partitions:

  • Checks on resolved values (the "when 'Fn::Sub' is resolved" W1031 findings) see the real partition and URL suffix.
  • E3716's length limit uses the right partition name. In eusc-* it falls by 1 (199 to 198 in eusc-de-east-1), because a real ARN there carries aws-eusc, not aws-iso-f. In us-isof-* it rises by 2 (197 to 199 in us-isof-east-1).

New W1031 findings in the other partitions. Some provider schemas hard-code the commercial partition in their patterns: aws|aws-cn|aws-us-gov in an ARN, a longer partition list that still leaves out aws-eusc, arn:aws:, or an amazonaws.com host. A !Sub built from ${AWS::Partition} or ${AWS::URLSuffix} used to resolve to the commercial values and pass those patterns in every region. It now resolves to the region's real values and fails them. For example:

Resources:
  Recorder:
    Type: AWS::Config::ConfigurationRecorder
    Properties:
      RoleARN: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/config

is silent on main in every region. With this change, eusc-de-east-1 and the regions of every other partition report:

W1031 {'Fn::Sub': 'arn:${AWS::Partition}:iam::${AWS::AccountId}:role/config'} does not match 'arn:(aws|aws-cn|aws-us-gov):iam::[0-9]*:(role)\\/.*' when 'Fn::Sub' is resolved

Commercial, GovCloud and China regions stay silent. The same pattern already rejects a literal value: RoleARN: arn:aws-eusc:iam::123456789012:role/config gets E3031 in eusc-de-east-1 on main. This change carries that schema gap over to the !Sub form as W1031, which still gives a non-zero exit code by default (--non-zero-exit-code defaults to informational).

The same happens for, among others, AWS::ServiceCatalog::LaunchRoleConstraint.RoleArn, AWS::ServiceCatalog::PortfolioPrincipalAssociation.PrincipalARN, AWS::ApiGatewayV2::Integration.CredentialsArn and AWS::Amplify::Branch (arn:aws: patterns), and for two AWS::AppRunner::Service properties: the ECR image identifier built from ${AWS::URLSuffix}, and the access role ARN, whose pattern lists aws-iso and aws-iso-b but not aws-eusc, aws-iso-e or aws-iso-f. Counting every pattern in the cached provider schemas (2026-10-31) that contains arn:aws:, aws|aws-cn|aws-us-gov, a partition list without aws-eusc, or a literal amazonaws.com host, roughly 120 of the 1876 resource types in the eusc-de-east-1 index have at least one, about 90 of them on a property that is not read-only. The W1031 only appears where a template builds that property with ${AWS::Partition} or ${AWS::URLSuffix}. A template of common resources (bucket, key and trust policies, Lambda with layers, Events, AWS::Lambda::Permission with ${AWS::URLSuffix} service principals, ECS with an ECR image, Step Functions, a VPC endpoint, outputs) gets no new findings in any region.

The ARN patterns are fixed at the source by aws-cloudformation/resource-provider-enhanced-schemas#78, which widens every partition-bound ARN pattern in the published schemas. With those schemas, the example above and the ARN properties listed get no W1031 in any region. The App Runner image identifier is a host pattern, which #78 does not touch. cfn-lint's own schemas had one partition-bound ARN pattern, the Step Functions Task Resource, which #4978 widens.

Why this stacks on #4976 and #4978. With the real partition resolved, a principal written as !Sub arn:${AWS::Partition}:iam::123456789012:root is checked against the principal pattern as arn:aws-eusc:... in eusc-de-east-1. Without #4976 that adds six W1031 findings on good/resources/properties/hard_coded_arn_properties.yaml in the regions of every other partition. With it, there are none. Without #4978, a Step Functions Definition whose Task Resource is !Sub arn:${AWS::Partition}:lambda:... gets a new W1031 in those regions too (it already gets one in China and GovCloud on main).

Verification.

  • test/unit/module/helpers/test_partitions.py: every region of the non-commercial partitions plus two commercial ones, the commercial fallback, and every region in REGIONS is either commercial or matched by the table.
  • test/unit/module/context/test_pseudo_values.py: AWS::Partition, AWS::URLSuffix, AWS::StackId and AWS::NotificationARNs follow the partition.
  • test_language_extensions.py: Fn::ForEach resolves AWS::Partition and AWS::URLSuffix for us-iso-east-1.
  • test_function_layer_arn_length.py: cases at and one past the limit for us-isof-east-1 and eusc-de-east-1. Three of them fail without this change.
  • Good fixtures linted one region at a time in all eight partitions (same command as fix(iam): accept IAM principal ARNs from every partition #4976): same output as without this change in every region.
  • pytest test and pre-commit run --all-files pass.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Three copies of the region-to-partition table existed (context, the
LanguageExtensions transform, and E3716) and disagreed with each other.
The first two knew only aws, aws-cn and aws-us-gov, so AWS::Partition
resolved to aws for every other region in REGIONS; E3716 mapped eusc-*
to aws-iso-f and us-isof-* to aws-iso. Replace them with one table in
helpers that follows botocore's endpoints.json regionRegex and dnsSuffix
values.

Signed-off-by: Brenden Hogan <hoganbr@amazon.com>
@kddejong
kddejong force-pushed the fix/partition-url-suffix-table branch from ed84e19 to 3fa150d Compare November 3, 2026 20:46
@codecov

codecov Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.80%. Comparing base (bcd52cd) to head (3fa150d).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4980      +/-   ##
==========================================
+ Coverage   94.74%   94.80%   +0.06%     
==========================================
  Files         441      441              
  Lines       16142    16124      -18     
  Branches     3140     3130      -10     
==========================================
- Hits        15293    15287       -6     
+ Misses        469      463       -6     
+ Partials      380      374       -6     
Flag Coverage Δ
unittests 94.80% <100.00%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kddejong
kddejong merged commit a6eee92 into aws-cloudformation:main Nov 3, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AWS::Partition does not resolve correctly for all partitions, and E3716 uses the wrong partition name

2 participants