Search code examples
amazon-web-servicesterraform-provider-awsinfrastructure

How do I create a new policy on runtime and attach it to a role without hardcoding the policy_document JSON in code resource?


I am trying to create some service users with specific roles. I don't want to hardcode the policy documents for my service role.

Example:

service-1 required read access to -EC2 instance, Cloudwatch logs and write access to s3 bucket.

Service-2 needs SNS, SQS, and DynamoDB.

Provider=AWS

Any help will be much appreciated.

How do I create a new policy on runtime and attach it to a role without hardcoding the policy_document JSON in code resource?


Solution

  • Apart from your question, there is a great document to read about HCL Language. https://github.com/hashicorp/hcl

    Now as far as I understand your question, it seems that you want to create a permission module and be able to pass it service-name and permission. That specific method will allow you to reuse the IAM role creation code. I suggest you read https://www.terraform.io/docs/configuration/modules.html.

    You can create a Module like IAM Permission and do something like

       resource "aws_iam_policy" "policy" {
     name        = "${var.service_name}"
     description = "${var.service_name} access policy"
     policy      = templatefile("${path.module}/ddb_role.tpl", {
       role            = var.role
     })
    }
    
    resource "aws_iam_role" "role" {
     name               = "role_${var.env}"
     assume_role_policy = "${file("assumerolelambdapolicy.json")}"
    }
    
    resource "aws_iam_role_policy_attachment" "policy_attachment" {
      role    = "${aws_iam_role.role.name}"
      policy_arn = "${aws_iam_policy.policy.arn}"
    } 
    

    Template file:

    {
        "Version": "2012-10-17",
        "Statement": [
    
         {
            "Effect": "Allow",
            "Action": ${role},
            "Resource": "*"
          }
      ]
    }
    

    var.tf you could store a list of permissions

    variable "role" {
        type = list
        default = [
     "sqs:*",
              "logs:CreateLogGroup",
              "logs:CreateLogStream",
              "logs:PutLogEvents",
              "ec2:Describe*",
              "ec2:DescribeSecurityGroups",
              "ec2:DescribeSubnets",
              "ec2:DescribeVpcs",
              "logs:CreateLogGroup",
              "logs:CreateLogStream",
              "logs:PutLogEvents",
              "ec2:CreateNetworkInterface",
              "ec2:DescribeNetworkInterfaces",
              "ec2:DeleteNetworkInterface"
    ]
    }
    

    This is something you should be able to override using tfvar file. Try this and let me know.