So while it's tempting to just give the terraform account admin access to everything, it's not a good security policy. It's still worth trying to make the permissions as restrictive as you reasonably can, for this user.
I split up my permissions as follows (there was no real need to, you can merge these templates into one json file). The arns etc are examples only and should not be copied verbatim (eg /bucket would be the name of your actual S3 bucket).
This is what ended up working for me:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "List",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucket"
]
},
{
"Sid": "ManageObjects",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::bucket/*"
]
},
{
"Sid": "SpecificTable",
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:DeleteItem",
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/xxx"
}
]
}
This is the initial policy I've started with, for provisioning infra via terraform incl compute, databases, and pushing images to ECR:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TerraformCore",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ec2:*",
"ecr:BatchCheckLayerAvailability",
"rds:DeleteDBSubnetGroup",
"rds:CreateDBInstance",
"rds:CreateDBSubnetGroup",
"rds:DeleteDBInstance",
"rds:DescribeDBSubnetGroups",
"rds:DescribeDBInstances",
"rds:ListTagsForResource",
"rds:ModifyDBInstance",
"iam:CreateServiceLinkedRole",
"rds:AddTagsToResource"
],
"Resource": "*"
},
{
"Sid": "PushImagesToECR",
"Effect": "Allow",
"Action": "ecr:*",
"Resource": "arn:aws:ecr:*:*:repository/xxx"
},
{
"Sid": "MaxEC2Size",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*:*:instance/*"
],
"Condition": {
"ForAnyValue:StringNotLike": {
"ec2:InstanceType": "t2.micro"
}
}
}
]
}
... where nnn is your account number and xxx is the relevant resource name. Also obviously modify regions etc as needed.
^ My fave part of the above is not letting this user provision any machines bigger than a t2.micro, lol
We all know AWS LURVES to get paid.
Also: do not change the version string to the current date: its the schema version number (schema against which aws will validate your json).