fix: keep literal arn in aws:SourceArn policy conditions - terraform cycle (#170)#172
Merged
awsandy merged 1 commit intoJul 15, 2026
Conversation
…ycle) A lambda execution role whose trust policy restricts assumption to the function using it carries that function's arn in an "aws:SourceArn" condition. Dereferencing the arn made the role depend on the lambda, which already depends on the role via role=, so terraform validate failed with: Error: Cycle: aws_lambda_function.X, aws_iam_role.Y AWS accepts the trust policy because the arn is predictable; terraform cannot order the graph. Keep the literal arn, mirroring the existing guard for policy Resource elements and the approach taken in aws-samples#137. Fixes aws-samples#170
Contributor
|
If you get chance to test/fix the caveat mentioned please do |
awsandy
pushed a commit
that referenced
this pull request
Jul 15, 2026
globals_replace keeps some lambda ARNs literal instead of de-referencing them to aws_lambda_function.<name>.arn: an aws:SourceArn policy condition or a policy Resource naming the function that owns the role (de-referencing those cycles - #170/#172), a wildcard, a cross-region function, or a function not collected in this run. Those literals were emitted with the account id and region hard-coded inline. Route them through a new sub_acct_region() helper that substitutes this account's id/region with data.aws_caller_identity / data.aws_region - the same substitution other ARN types already get later in globals_replace. The function name stays literal, so the #172 cycle fix is preserved; an ARN in a different account (this account's id absent) is left fully literal.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #170.
Problem
A full-account import aborts at validation with a dependency cycle:
The trigger is a lambda execution role whose trust policy restricts assumption to the very function that uses it, via an
aws:SourceArncondition. Several vendor-supplied CloudFormation stacks emit execution roles shaped like this, so it isn't an unusual shape - and it takes the whole run down, importing nothing.What
generate-config-outproduces:fixtf then de-references that arn, so the role points at the function:
while the function necessarily points back at the role:
AWS accepts the trust policy because the arn is predictable. Terraform cannot order the graph, so
validatefails.Fix
Keep the literal arn when the attribute is an
aws:SourceArnpolicy condition, mirroring the guard that already sits three lines above it for policyResourceelements:This is the same principle as #137 (keep account-portable role arns literal in policy documents), extended from policy
Resourceelements to policy condition keys: an arn inside an IAM policy document should stay literal.Testing
Environment: aws2tf v6273, terraform 1.15.8, AWS provider 6.53.0, python 3.12.
-f) that aborted atexit 020. With this changeterraform validatepasses, stage 7 plans clean (0 to add, 0 to destroy) and the run imports to completion."aws:SourceArn"and"AWS:SourceArn"now keep the literal;Resourcestill keeps the literal; an ordinary lambda arn attribute (function_arn = "arn:aws:lambda:...") still de-references toaws_lambda_function.<name>.arn. Normal de-referencing is unaffected..tffiles afterwards to confirm no cycles remained anywhere else in the config, not just the one terraform happened to report first.One caveat
The kept literal leaves the account id and region inline, exactly as the existing
Resourceguard does - the lambda branch returns before reaching the account/regionformat(...)substitution that other arn types get. Letting these fall through to that substitution would be the nicer end state, but it would also change theResource, wildcard and cross-region cases, so I've kept it out of this fix. Happy to follow up if you want it.