I have the following resource:
resource "aws_iam_user_policy" "ses_send_policy" {
count = var.enabled ? 1 : 0
name_prefix = var.user_policy_name_prefix
user = aws_iam_user.ses_smtp_user[0].name
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ses:SendEmail",
"ses:SendRawEmail"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"ses:FromAddress": [
"${var.user_email_address}"
]
}
}
}
]
}
EOF
}
I'd like to ask how to make the "Condition" block in the policy optional and based on a bool type variable? I want to have it only if var.condition = true
.
In the documentation for
aws_iam_user_policy
at the time of this answer the main usage example shows settingpolicy
like this:Notice that it recommends using the
jsonencode
function to produce the entire value, rather than trying to construct JSON from parts via template concatenation, since that ensures that the result will always be valid JSON syntax.It also has the benefit that you can use any expressions you need to make dynamic decisions about the data structure. In your case you already have a dynamic reference to the user's email address from a variable, so let's start by translating what you have into a form more like the example in the documentation:
Notice that the value is now written in Terraform's own expression syntax, rather than JSON syntax. Terraform will construct the valid JSON syntax itself as part of evaluating the
jsonencode
function call.Your new requirement is to omit
Condition
entirely in certain cases. To describe that requirement as a Terraform expression requires merging the object which describes the parts that are always present (Effect
,Action
, andResource
) with another expression which describes the optional parts.For example:
What I've changed here is a bit subtle and perhaps hard to see with all of the other content that didn't change, so here's a cut down version with some of the previous elements replaced by comments just to make the new content more prominent:
The
merge
function takes multiple objects and returns a single object containing the elements from all of them taken together. In this case, the second argument tomerge
is a more complex expression which produces either an object with aCondition
attribute or an empty object depending on the condition value. Merging an empty object into an object changes nothing about the result, and so in this case the condition controls whether that second argument will contribute any attributes at all.You can use a aws_iam_policy_document resource, and make condition block dynamic.