I’m trying to restrict access to the state lock management DynamoDB table. (Terraform)
I understand that DynamoDB does not support resource based policies and you have to set it in a role, however I’m not actually 100% sure of that either.
The thing is that, although the policy applies greatly, it is not working. Variable details are perfekt. Important is to say I authenticate to Terraform with Short Term credentials by setting the AWs environments variables you get in the Portal and I have Administrator Access. However, I understand that an explicit deny always overwrites any allows.
I know that it is not working because I change the value of IP variable to something different and I am still able to obtain statelock info when terraform apply.
json (I have tried allow also)
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "dynamodb:*",
"Condition": {
"NotIpAddress": {
"aws:SourceIp": <myip>
}
},
"Effect": "Deny",
"Resource":<myarn>
}
]
}
This is how it looks using data iam policy document
resource "aws_iam_role" "role" {
name = "${var.dynamodb_name}-ip-restrict-role"
assume_role_policy = data.aws_iam_policy_document.assume_role.json
}
data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["dynamodb.amazonaws.com"]
}
actions = ["sts:AssumeRole"]
}
}
resource "aws_iam_role_policy" "dynamodb_policy" {
name = "${var.dynamodb_name}-ip-restrict-policy"
policy = data.aws_iam_policy_document.dynamodb_policy_document.json
role = aws_iam_role.role.id
}
data "aws_iam_policy_document" "dynamodb_policy_document" {
statement {
resources = [aws_dynamodb_table.dynamodb.arn]
effect = "Deny"
actions = [
"dynamodb:*"
]
condition {
test = "NotIpAddress"
variable = "aws:SourceIp"
values = var.whitelisted_ips_dynamo
}
}
}
2
Answers
You’re correct, that DynamoDB supports no resource-based permissions that would allow you to limit access to certain IP addresses.
I tried your setup with this policy on my IAM User:
Any I was successfully locked out:
Changing the
SourceIp
to my actual IP allowed me to describe the table (the user has an admin policy).I suggest you check you double check your IPs and resource ARN, the policy itself looks fine aside from that.
I would use a VPCe policy for this, if the requests are coming from within AWS (EC2, Lambda, etc…).
Adding a VPCe for DynamoDB adds no additional cost, but forces all of your traffic to go via the endpoint, which allows you to specify its own IAM policy, which treats it almost like a resource based policy, that you don’t have to define on each role/user.
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/vpc-endpoints-dynamodb.html