So I am trying to assign multiple policies to users which i have defined in policies.tf file and when running it is showing an error. I am using gitlab to run this, also i am able to solve this error if i am defining s3_policy directly like aws_iam_policy.s3_policy.arn
resource "aws_iam_policy" "s3_policy" {
name = "s3-policy"
description = "S3 IAM policy"
# Define the policy document with the required permissions
policy = <<-JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "*"
}
]
}
JSON
}
resource "aws_iam_policy" "ec2_policy" {
name = "ec2-policy"
description = "EC@ IAM policy"
# Define the policy document with the required permissions
policy = <<-JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}
]
}
JSON
}
# Your aws_iam_user_policy_attachment resource definition
resource "aws_iam_user_policy_attachment" "user_policies" {
for_each = toset(var.user_policies)
user = module.iam_user_module.aws_iam_user.this[0].name
policy_arn = aws_iam_policy[each.value].arn
}
The error i am getting is
Error: Invalid reference
│
│ on modules/iam_module/policies.tf line 43, in resource "aws_iam_user_policy_attachment" "user_policies":
│ 43: policy_arn = aws_iam_policy[each.value].arn
│
│ A reference to a resource type must be followed by at least one attribute
│ access, specifying the resource name.
>Solution :
The policy resource was created without using for_each meta-argument, so you need to use the following:
resource "aws_iam_policy" "s3_policy" {
name = "s3-policy"
description = "S3 IAM policy"
# Define the policy document with the required permissions
policy = <<-JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "*"
}
]
}
JSON
}
resource "aws_iam_policy" "ec2_policy" {
name = "ec2-policy"
description = "EC2 IAM policy"
# Define the policy document with the required permissions
policy = <<-JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}
]
}
JSON
}
# Your aws_iam_user_policy_attachment resource definition
resource "aws_iam_user_policy_attachment" "ec2_policy" {
user = module.iam_user_module.aws_iam_user.this[0].name
policy_arn = aws_iam_policy.ec2_policy.arn
}
resource "aws_iam_user_policy_attachment" "s3_policy" {
user = module.iam_user_module.aws_iam_user.this[0].name
policy_arn = aws_iam_policy.s3_policy.arn
}
Note that when using implicit references, the syntax is:
<resource type>.<logical name>.<attribute>
or in your case
| aws_iam_policy | ec2_policy | arn
| resource type | logical name | attribute
Since the policy is assigned to the same user, alternatively what can be done is the following:
resource "aws_iam_policy" "iam_policies" {
name = "ec2-s3-policy"
description = "EC2 and S3 IAM policy"
# Define the policy document with the required permissions
policy = <<-JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}
]
}
JSON
}
# Your aws_iam_user_policy_attachment resource definition
resource "aws_iam_user_policy_attachment" "user_policy" {
user = module.iam_user_module.aws_iam_user.this[0].name
policy_arn = aws_iam_policy.iam_policy.arn
}