skip to Main Content

I reference the code at https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile, I created iam.tf file. I tried to attach the policy to an ec2 instance. I got an error:

aws_iam_role.role: Creating...
Error: failed creating IAM Role (jenkins_server_role): MalformedPolicyDocument: Has prohibited field Resource
status code: 400, request id: c2b8db57-357f-4657-a692-a3e6026a6b7b

with aws_iam_role.role,
on iam.tf line 6, in resource "aws_iam_role" "role":
6: resource "aws_iam_role" "role" Releasing state lock. This may take a few moments...
ERRO[0011] Terraform invocation failed in /home/pluo/works/infra/jenkins
ERRO[0011] 1 error occurred:
        * exit status 1

Here is the iam.tf:

resource "aws_iam_instance_profile" "jenkins_server" {
  name = "jenkins_server"
  role = aws_iam_role.role.name
}

resource "aws_iam_role" "role" {
  name = "jenkins_server_role"
  path = "/"

  assume_role_policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": "ec2:*",
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "elasticloadbalancing:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "cloudwatch:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "autoscaling:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:AWSServiceName": [
                        "autoscaling.amazonaws.com",
                        "ec2scheduled.amazonaws.com",
                        "elasticloadbalancing.amazonaws.com",
                        "spot.amazonaws.com",
                        "spotfleet.amazonaws.com",
                        "transitgateway.amazonaws.com"
                    ]
                }
            }
        }
    ]
}
EOF
}

Here is the module to create ec2 instance.

module "ec2" {
  source                       = "terraform-aws-modules/ec2-instance/aws"
  version                      = "4.1.4"

  name                        = var.ec2_name
  ami                         = var.ami
  instance_type               = var.instance_type
  availability_zone           = var.availability_zone
  subnet_id                   = data.terraform_remote_state.vpc.outputs.public_subnets[0]
  vpc_security_group_ids      = [aws_security_group.WebServerSG.id]
  associate_public_ip_address = true

  key_name                    = var.key_name
  monitoring                  = true

  iam_instance_profile        = aws_iam_instance_profile.jenkins_server.name

  enable_volume_tags          = false
  root_block_device = [
    {
      encrypted   = true
      volume_type = "gp3"
      throughput  = 200
      volume_size = 100
      tags = {
        Name = "jenkins_server"
      }
    },
  ]

  tags = {
    Name = "WebServerSG"
  }
}

2

Answers


  1. Your assume_role_policy is incorrect. For ec2 instances it should be:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": { "Service": "ec2.amazonaws.com"},
          "Action": "sts:AssumeRole"
        }
      ]
    }
    

    Then you current assume_role_policy should be written in aws_iam_role_policy instead.

    Login or Signup to reply.
  2. Just to provide more information on top of the good answer from Marcin. In AWS IAM roles there are two kinds of policies you might specify (which at first might be confusing):

    • assume role policy – i.e. "who"/what can assume this role, as Marcin mentions here you would like to specify that EC2 instances can assume this role – i.e. act in this role

    • role policy – i.e. what can this role do; in your case it will be all these elasticloadbalancing, cloudwatch, etc.

    So, putting that into Terraform perspective:

    • the former should go to assume_role_policy of a aws_iam_role
    • the latter should go to a separate resource "iam_role_policy"
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search