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"
}
]
})
}