Skip to content

refactor: remove E3511 in favour of the E1156 role ARN format - #4942

Merged
kddejong merged 1 commit into
aws-cloudformation:mainfrom
kddejong:fix/issue/4941
Oct 27, 2026
Merged

kddejong merged 1 commit into
aws-cloudformation:mainfrom
kddejong:fix/issue/4941

Conversation

@kddejong

Copy link
Copy Markdown
Contributor

Important

Merge gate — do not merge until cfn-lint --update-specs shows all four properties carrying their formats.
Merging before that leaves EC2::SpotFleet IamFleetRole and S3::Bucket ReplicationConfiguration/Role with no role check at all.

Status: the gate is already satisfied. The enhanced-schemas rebuild triggered by
aws-cloudformation/resource-provider-enhanced-schemas#74 republished schemas-cfn-lint.zip at
2026-10-27T16:56:40Z (release schema_date 2026-10-27T16:56:37Z). Re-confirm before merging:

cfn-lint --update-specs
python -c "
from cfnlint.schema.manager import PROVIDER_SCHEMA_MANAGER as M
for t, p in [
    ('AWS::EC2::SpotFleet', '/definitions/SpotFleetRequestConfigData/properties/IamFleetRole'),
    ('AWS::S3::Bucket', '/definitions/ReplicationConfiguration/properties/Role'),
    ('AWS::Batch::ComputeEnvironment', '/properties/ServiceRole'),
    ('AWS::Batch::ComputeEnvironment', '/definitions/ComputeResources/properties/SpotIamFleetRole'),
]:
    s = M.get_resource_schema('us-east-1', t).schema
    for k in p.strip('/').split('/'):
        s = s[k]
    print(t, p, '->', {k: v for k, v in s.items() if k in ('format', 'anyOf')})
"

Expected: format: AWS::IAM::Role.Arn on the first two, anyOf: [Role.Arn, Role.Name] on the two Batch paths.

Fixes #4941

Problem

E3511 (RoleArnPattern) carried a hardcoded list of six property paths and its own inline regex, duplicating the AWS::IAM::Role.Arn format rule E1156.

On the four ARN-only paths it reported every bad value twice, under two rule IDs whose patterns disagree:

E1156  'bogusname' is not a 'AWS::IAM::Role.Arn' with pattern '^arn:aws[a-zA-Z-]*:iam::\d{12}:role/.+$'
E3511  'bogusname' does not match '^arn:(aws[a-zA-Z-]*)?:iam::\d{12}:role/[a-zA-Z_0-9+=,.@\-_/]+$'

E3511 made the partition optional (arn::iam::... is not a valid ARN) and restricted the path charset; E1156 requires a partition and leaves the path unrestricted.

On the two AWS::Batch::ComputeEnvironment paths it was actively wrong. ServiceRole and ComputeResources/SpotIamFleetRole accept a role name or a path-prefixed role name as well as an ARN, and E3511 rejected all of those:

'AWSBatchServiceRole'                FIRES   <- bare name, deploys (#4838)
'/service-role/AWSBatchServiceRole'  FIRES   <- documented path-prefixed form
'/foo/bar'                           FIRES   <- the Batch API model's own example

Evidence for the constraint

The constraint now lives in the resource schemas, added in aws-cloudformation/resource-provider-enhanced-schemas#74 (merged 2026-10-27):

Property Schema constraint Accepts
Backup::BackupSelection BackupSelection/IamRoleArn format: AWS::IAM::Role.Arn ARN
ECS::TaskDefinition ExecutionRoleArn format: AWS::IAM::Role.Arn ARN
EC2::SpotFleet SpotFleetRequestConfigData/IamFleetRole format: AWS::IAM::Role.Arn ARN only
S3::Bucket ReplicationConfiguration/Role format: AWS::IAM::Role.Arn ARN only
Batch::ComputeEnvironment ServiceRole anyOf: [Role.Arn, Role.Name] ARN or name
Batch::ComputeEnvironment ComputeResources/SpotIamFleetRole anyOf: [Role.Arn, Role.Name] ARN or name

The per-property accept/reject behaviour was measured in us-east-1 on 2026-10-26; the verbatim service errors are recorded on the enhanced-schemas issue. The AWS::IAM::Role.Name format used by the two Batch paths landed as E1165 in #4936.

So every path E3511 covered is now covered by E1156, and the two Batch paths additionally by E1165 — without the false positives.

Changelog note

Anyone suppressing this rule with ignore_checks: [E3511] will start seeing E1156 (and E1165 on the two Batch paths) instead. An existing suppression needs updating, not silently widening — a stale E3511 entry becomes a no-op.

Verification

Verified against both the published schemas and a locally built schema set (enhanced-schemas upstream/main with #74, assembled into a fresh directory and selected via XDG_CACHE_HOME). Both produce identical results, so there is no interval where a property loses its check.

cfn-lint --update-specs
pytest test                      # 19 failed, 3208 passed
pre-commit run --all-files       # all hooks pass
cfn-lint --update-documentation  # regenerates the docs/rules.md row
cfn-lint --format parseable -t "test/fixtures/templates/good/**/*.yaml"

The 19 test failures are pre-existing and environmental (missing pydot, junit-xml, jschema-to-python, and cfn-lint not on PATH for the integration tests). Confirmed identical on a pristine main worktree: the failure sets diff clean, and the pass count moves 3212 -> 3208, exactly the four parametrized cases in the deleted test file.

The four ARN-only properties still report, now under E1156

a-arn-only-bad.yaml:8:9:E1156:'AWSBatchServiceRole' is not a 'AWS::IAM::Role.Arn' ...   # SpotFleet IamFleetRole
a-arn-only-bad.yaml:18:9:E1156:'AWSBatchServiceRole' is not a 'AWS::IAM::Role.Arn' ...  # S3 ReplicationConfiguration/Role
a-arn-only-bad.yaml:31:9:E1156:'bogusname' is not a 'AWS::IAM::Role.Arn' ...            # Backup IamRoleArn
a-arn-only-bad.yaml:37:7:E1156:'bogusname' is not a 'AWS::IAM::Role.Arn' ...            # ECS ExecutionRoleArn

Valid templates confirmed silent

Both Batch properties, each of these five forms (10 cases), all silent — three of them were E3511 false positives before this change:

Value Before After
AWSBatchServiceRole (bare name) E3511 silent
/foo/bar (API model's example) E3511 silent
/service-role/AWSBatchServiceRole E3511 silent
arn:aws:iam::123456789012:role/AWSBatchServiceRole silent silent
arn:aws:iam::123456789012:role/aws-service-role/batch.amazonaws.com/AWSServiceRoleForBatch silent silent

Unresolvable values stay silent on all six properties — !Ref, !GetAtt, !Sub, and !If over a mix of the two.

The good/ fixture sweep is byte-identical before and after against the same schema cache (168 findings both). E3511 never fired on the good fixtures, so nothing there changes.

Both Batch properties still report bad values

c-batch-invalid.yaml:8:7:E1156:'bad name with spaces' is not a 'AWS::IAM::Role.Arn' ...
c-batch-invalid.yaml:8:7:E1165:'bad name with spaces' is not a 'AWS::IAM::Role.Name' ...
c-batch-invalid.yaml:19:7:E1156:'arn:aws:iam::123456789012:notarole/x' is not a 'AWS::IAM::Role.Arn' ...
c-batch-invalid.yaml:19:7:E1165:'arn:aws:iam::123456789012:notarole/x' is not a 'AWS::IAM::Role.Name' ...

Both anyOf branches fail, so both formats are reported — expected, and 123456789012 is AWS's documentation placeholder account.

Related

#4926 fixes only the Batch ServiceRole false positive, with a path-based exemption inside E3511 keyed on the property name. This change removes the rule entirely, so #4926 becomes unnecessary — leaving it open for a maintainer to decide rather than closing it here.

pytest -m data was not run: nothing under src/cfnlint/data/ is touched.

E3511 carried a hardcoded list of six property paths and its own inline
regex, duplicating the AWS::IAM::Role.Arn format rule E1156. On the four
paths that are ARN-only it reported every bad value twice, under two rule
IDs with two disagreeing patterns.

On the two AWS::Batch::ComputeEnvironment paths it was actively wrong:
ServiceRole and ComputeResources/SpotIamFleetRole accept a role name or a
path-prefixed role name as well as an ARN, and E3511 rejected both.

All six properties now carry their constraint in the resource schemas --
format: AWS::IAM::Role.Arn on the four ARN-only paths, and
anyOf: [Role.Arn, Role.Name] on the two Batch paths -- so E1156 and E1165
cover them without the false positives.

Users suppressing E3511 via ignore_checks will see E1156 (and E1165 on the
Batch paths) instead, so an existing suppression needs updating rather
than silently widening.

Fixes aws-cloudformation#4941
@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.68%. Comparing base (9b0e661) to head (c72e5c9).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4942      +/-   ##
==========================================
- Coverage   94.68%   94.68%   -0.01%     
==========================================
  Files         442      441       -1     
  Lines       16077    16058      -19     
  Branches     3116     3114       -2     
==========================================
- Hits        15223    15204      -19     
  Misses        470      470              
  Partials      384      384              
Flag Coverage Δ
unittests 94.67% <ø> (-0.01%) ⬇️

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 marked this pull request as ready for review October 27, 2026 17:24
@kddejong
kddejong merged commit 6e5000d into aws-cloudformation:main Oct 27, 2026
23 of 24 checks passed
@kddejong
kddejong deleted the fix/issue/4941 branch October 27, 2026 17:26
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.

Delete E3511 once the IAM role ARN formats land in enhanced-schemas

1 participant