IfExists
to the rescue)You have a deployment pipeline that uses Terraform to provision resources in AWS. This pipeline
assumes a role (let’s call it deployment-role
), which grants it the permissions
create/update/destroy these resources.
To make sure the role is scoped as narrowly as possible, you want to make sure that it only affects
resources that have a certain tag. For example, a Name
tag that starts with your-team
.
You add the following condition to role’s IAM policy statements:
"Condition": {
"StringLike": {
"aws:ResourceTag/Name" : "your-team*"
}
}
You update your Terraform to provision some new resources. You definitely make sure they have the
Name
tag begin with your-team
.
The deployment pipeline job errors. terraform apply
had this to say:
Error: ... AccessDeniedException: User: arn:sts::123456789012:assumed-role/deployment-role is not
authorised to perform {action} on resource: because no identity-based policy allows the {action}
action
The resource doesn’t exist yet, so it doesn’t have a Name
tag attached to it. Therefore, the role
can’t act on it. Kind of obvious, in retrospect…
Instead of using StringLike
, StringNotEquals
, etc, use the IfExists
form of these Conditions:
"Condition": {
"StringLikeIfExists": {
"aws:ResourceTag/Name" : "your-team*"
}
}
This will allow the action to go forward if the target resource does not yet have a tag (or whatever the condition key you’re using).
Funnily enough, on the AWS docs for global condition
keys (as
of 2025-08-27, at least), these IfExists
conditions are mentioned right at the top of the page, in
a “Note” box… Oh well.
Of course, this means that resources that do exist but don’t have the specific tag you’re looking for can now be acted upon by your role, so this creates different problems when trying to enforce least privilege.
More in-depth docs on IfExists
operators:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_IfExists