iam (terraform)

Sample: Create an execution role for Lambda@Edge

modules/iam/variables.tf

variable "tags_common" {

  description = "Common tags map: env, ci, department, program"

  type        = map(string)

  nullable    = false

}

variable "env" {}

variable "ci" {}


modules/iam/outputs.tf

output "role_lambdaedge_exec_arn" {

  sensitive = false

  value = aws_iam_role.lambdaedge_exec.arn

}


modules/iam/iam.tf

#Lambda@Edge execution role with permission to upload logs to CloudWatch and trigger from CloudFront

resource "aws_iam_role" "lambdaedge_exec" {

  #Required args

  assume_role_policy = <<EOF

{

    "Version": "2012-10-17",

    "Statement": [

        {

            "Effect": "Allow",

            "Principal": {

                "Service": [

                    "edgelambda.amazonaws.com",

                    "lambda.amazonaws.com"

                ]

            },

            "Action": "sts:AssumeRole"

        }

    ]

}

EOF

  #Optional args

  description = "${var.env}-${var.ci} Lambda@Edge execution role with permission to upload logs to CloudWatch and trigger from CloudFront"

  name        = "${var.env}-${var.ci}-lambdaedge-role"

  path        = "/${var.env}/${var.ci}/"

  tags        = var.tags_common

}

Sample: Create an user and give it access to S3 bucket

References: fwdefense, gdd

modules/iam/variables.tf

# Tags

variable "COUEnv" {}

variable "ci" {}

variable "Department" {}

variable "Program" {}


#

variable "name_service_user" {}

variable "bucket_data1_arn" {}

variable "bucket_data1_id" {}

modules/iam/outputs.tf

# Service account user, access key id

output "access_key_id" {

  value = aws_iam_access_key.user_keys.id

  sensitive = false

}

# Service account user, secret access key

output "secret_access_key" {

  #value = aws_iam_access_key.user_keys.encrypted_secret

  value = aws_iam_access_key.user_keys.secret

  sensitive = true

}

modules/iam/iam.tf

# we need a service account user

resource "aws_iam_user" "user" {

  name = var.name_service_user

}



# generate keys for service account user

resource "aws_iam_access_key" "user_keys" {

  user = "${aws_iam_user.user.name}"

}



modules/s3/variables.tf

...

variable "user_finalwork_arn" {}

modules/s3/outputs.tf

...

output "bucket_finalwork_id" {

  value = aws_s3_bucket.finalwork_s3.id

}


output "bucket_finalwork_arn" {

  value = aws_s3_bucket.finalwork_s3.arn

}

modules/s3/s3.tf

Grant finalwork_user access to the finalwork_bucket.

Note: better centralize the policy in the s3 module, otherwise different policies would overwrite each other!

Modify the policy for your specific needs.

resource "aws_s3_bucket_policy" "finalwork_policy" {

  bucket = aws_s3_bucket.finalwork_s3.id

  policy = data.aws_iam_policy_document.finalwork_allow_access.json

}


data "aws_iam_policy_document" "finalwork_allow_access" {

  #Access from backend

  statement {

    sid = "backendPerm"

    principals {

      type        = "AWS"

      identifiers = [var.role_s3_lambda]

    }

    actions = [

      "s3:*"

    ]

    resources = [

      aws_s3_bucket.finalwork_s3.arn,

      "${aws_s3_bucket.finalwork_s3.arn}/*",

    ]

  }

  #Access for: Browser based Amazon S3 uploading using HTTP POST

  statement {

    sid = "browserBasedUploadAndPresignedUrlDownload"

    principals {

      type        = "AWS"

      identifiers = [var.user_finalwork_arn]

    }

    actions = [

      "s3:GetObject",

      "s3:PutObject"

    ]

    resources = [

      "${aws_s3_bucket.finalwork_s3.arn}/final_work_doc/*"

    ]

  }

}




Sample: Create a role and give it access to Dynamo DB

modules/iam/variables.tf

# Tags

variable "COUEnv" {}

variable "ci" {}

variable "Department" {}

variable "Program" {}

#

variable "legacy_principal" {

  description = "AWS account ID where the another accessing application is deployed"

}

modules/iam/outputs.tf

#

modules/iam/iam.tf

data "aws_caller_identity" "current" {}

data "aws_region" "current" {}


locals {

  account_id  = data.aws_caller_identity.current.account_id

  region_name = data.aws_region.current.name

}


resource "aws_iam_role" "myapp_otherapp_role" {

  name = "${var.var_COUEnv}-${var.var_ci}-otherapp-role"

  max_session_duration = 10800


  assume_role_policy = jsonencode({

    Version = "2012-10-17",

    Statement = [

      {

        Effect = "Allow",

        Principal = {

          AWS = "arn:aws:iam::${var.legacy_principal}:root"

        },

        Action    = "sts:AssumeRole",

        Condition = {}

      }

    ]

  })

}



resource "aws_iam_role_policy" "myapp_otherappp_policy" {

  name = "${var.var_COUEnv}-${var.var_ci}-otherapp-policy"

  role = aws_iam_role.myapp_otherapp_role.id


  policy = jsonencode(

    {

      Version = "2012-10-17",

      Statement = [

        {

          Sid    = "dinamoall0",

          Effect = "Allow",

          Action = [

            "dynamodb:BatchGet*",

            "dynamodb:BatchWriteItem",

            "dynamodb:ConditionCheck*",

            "dynamodb:DeleteItem",

            "dynamodb:Describe*",

            "dynamodb:Get*",

            "dynamodb:List*",

            "dynamodb:PartiQLDelete",

            "dynamodb:PartiQLInsert",

            "dynamodb:PartiQLSelect",

            "dynamodb:PartiQLUpdate",

            "dynamodb:PutItem",

            "dynamodb:Query",

            "dynamodb:Scan",

            "dynamodb:UpdateItem",

          ]

          Resource = "arn:aws:dynamodb:*:${local.account_id}:table/${var.var_COUEnv}-${var.var_ci}-EmailRedirect"

        }

      ]

  })

}