Reputation: 67
I am trying to apply different actions for different IAM users, through Terraform, using the aws_iam_policy_document data source. Let's take as an example the following KMS Key policy statement:
data "aws_iam_policy_document" "kms_key_policy" {
statement {
sid = "Allow use of the key"
principals {
type = "AWS"
identifiers = var.A == true ? [ARN1, ARN2] : [ARN1]
}
actions = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]
resources = ["*"]
}
}
In the policy above I want to restrict the first two actions
to the ARN2, but keep the ARN1 with all the actions
that are originally in the actions block. Of course that I could just add another statement and separate both logics (as shown below) but I was trying to keep all the logic into the same statement
and avoid repeating code:
statement {
sid = "Allow ARN1 use of the key"
principals {
type = "AWS"
identifiers = [ARN1]
}
actions = [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]
resources = ["*"]
}
statement {
sid = "Allow ARN2 use of the key"
principals {
type = "AWS"
identifiers = var.A == true ? [ARN2] : []
}
actions = [
"kms:Encrypt",
"kms:Decrypt"
]
resources = ["*"]
}
I've already tried to add a condition similar to what is being used to check for the presence of ARN2 (in case var A is defined) but I was restricting ARN1 actions with the ARN2 one's (if ARN2 was present), as can be observed below:
actions = var.A == true ? ["kms:Encrypt", "kms:Decrypt"] : ["kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey"]
How could I separate the actions
for the different principal identifiers
ARNs inside the same statement
?
Upvotes: 1
Views: 1064
Reputation: 2032
What you're describing is not possible, as you can't make the list of actions a function of the principal during policy evaluation. That's not a Terraform limitation but how these AWS statements work. The conditionals you write here are evaluated when you apply the Terraform code, not during policy evaluation.
You never want to allow the same list of actions for both principals, regardless of the value of var.A
, so you will need always need at least two statements. I hope this make sense to you.
I'd propose something like this:
statement {
sid = "AllowEncryptDecrypt"
principals {
type = "AWS"
identifiers = var.A == true ? [ARN1, ARN2] : [ARN1]
}
actions = [
"kms:Encrypt",
"kms:Decrypt",
]
resources = ["*"]
}
statement {
sid = "AllowOtherKeyUse"
principals {
type = "AWS"
identifiers = [ARN1]
}
actions = [
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey",
]
resources = ["*"]
}
I'd argue there's no real repetition here, as there's no overlap between the lists of actions.
Upvotes: 2