4
votes

I am creating a role in AWS using terraform. Since IAM is non-region service, i just want to create the role once. So whenever I run the terraform it should check if the role already exists or not, if not it should create one.

data "aws_iam_role" "iam_role_check" {
  name = "some_role"
}

resource "aws_iam_role" "iam_role" {
  count= "${data.aws_iam_role.iam_role_check != "null" ? 0 : 1}"
  name = "some_role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

data.aws_iam_role.iam_role_check: Refreshing state...

Error: error reading IAM Role (some_role): NoSuchEntity: The role with name some_role cannot be found. status code: 404, request id:

3
this is what terraform is doing by default. checks if a resource already exists or not, if not it creates oneofirule
That is only true if I have .tfstate file. For example, if I am creating a workspace for us-east-1 and provisioned resources, now role is created in AWS and .tfstate file is under workspace us-east-1. What if I create one more workspace for us-east-2 and run the terraform again, since there is no .tfstate file it will again try to provision the role. My requirement is to run the same terraform(which has lambda function to deploy in all regions) in all AWS regions and provision the role only once.Deepan
Added my answer. I think you should edit the post, since the scenario you described is not clear from reading the post aloneofirule

3 Answers

2
votes

I think the simplest solution for this scenario is to create a separate state only for shared resources and run apply on it before running apply on other states

2
votes

I had a similar issue like this. I wrote a python script which checks IAM role exists or not. Based on that, it will set the count variable value (0/1) in tfvar file. Only with terraform, it was not achievable.

1
votes

There is no known way because it’s design principle, see this GitHub issue.

I think there is nothing wrong with creating as many roles as you need. You may include some distinguishing bits in the role name, like deployment name or environment. You also may want to separate some common configurations to other “common” terraform deploy and use just data sources in other places.

When there is no way to have many instances for the same thing, like AWSServiceRoleForAmazonElasticsearchService for the Amazon Elasticsearch Service, Cloud Posse, for example, made a simple variable if the role should be created or not in their terraform Elasticsearch module, search for create_iam_service_linked_role in the README.md.