// This file sets up an IAM user with the permissions to
// have read-only access to an AWS account's infrastructure.
//
// The AWS managed ReadOnlyAccess policy will be attached to the
// new IAM user, however particular care has been taken to attach
// an additional policy which *retracts* potentially invasive policy
// actions like s3:Get*.
//
//
// Instructions
// ============
//
// Place this file in a directory, then cd to that folder and run:
//
//     terraform init
//     terraform apply
//     (then enter a username, eg: tfstate.com)
//
// When it is all finished obtain the Key ID and the Secret by running:
//
//     terraform output key_id
//     terraform output key_secret
//
// Then return to tfstate.com and enter those values in.


provider "aws" {
  region = "us-west-2"  # irrelevant for IAM
}

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
    }
  }
}


// The username of the new IAM user, prompt the user
variable "username" {
  # default = "tfstate.com"
}

// Make the username print out
output "username" {
  value = var.username
}

// Generate an Access Key ID and Secret as outputs
output "key_id" {
  value = aws_iam_access_key.main.id
}

// This value can only be obtained by running: terraform output key_secret
output "key_secret" {
  sensitive = true
  value = aws_iam_access_key.main.secret
}

// New IAM user, feel free to rename the username
resource "aws_iam_user" "main" {
  name = var.username
}

// New IAM access key
resource "aws_iam_access_key" "main" {
  user    = aws_iam_user.main.name
}

// Attach AWS managed ReadOnlyAccess policy, see below for policy retractions
resource "aws_iam_user_policy_attachment" "read-only" {
  user       = aws_iam_user.main.name
  policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}


// We are specifically retracting these permissions from the default AWS
// ReadOnlyAccess policy because these items aren't related to infrastructure
// configuration drift management and are a significant security and privacy
// risk.
//
// A DENY policy ALWAYS overrides an ALLOW policy
resource "aws_iam_user_policy" "forbidden-actions" {
  name   = "tfstatecom-forbidden-actions"
  user   = aws_iam_user.main.name
  policy = <<EOD
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Resource": "*",
            "Action": [
                "acm:Get*",
                "athena:Get*",
                "backup:Get*",
                "ce:Get*",
                "chime:Get*",
                "cloudwatch:Get*",
                "dynamodb:*Item*",
                "glue:*GetJob*",
                "logs:GetLog*",
                "s3:GetObject"
            ]
        }
    ]
}
EOD
}

