// This file sets up an IAM Role 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 role, 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 role name, eg: tfstate)
//
//     terraform output role
//
// Then return to tfstate.com and enter that value in.


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

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

output "role" {
  value = aws_iam_role.main.arn
}

// The per-client externalId, used for security
variable "external_id" {
  description = "An External ID which can be obtained by logging into tfstate.com and navigating to Infra -> Configure -> AWS Role -> External ID"
}

output "external_id" {
  value = var.external_id
}

// New IAM Role
resource "aws_iam_role" "main" {
  name = "tfstatecom"  # don't change this
  assume_role_policy = <<EOD
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::995163501499:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringLike": {
          "sts:ExternalId": "${var.external_id}"
        }
      }
    }
  ]
}
EOD
}

// Attach AWS managed ReadOnlyAccess policy, see below for policy retractions
resource "aws_iam_role_policy_attachment" "read-only" {
  role       = aws_iam_role.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_role_policy" "forbidden-actions" {
  name   = "tfstatecom-forbidden-actions"
  role   = aws_iam_role.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
}

