data "aws_iam_policy_document" "read_only_mfa" {
  count = var.require_mfa ? 1 : 0

  statement {
    sid = "AllowLimitedReadOnlyAccess"

    effect = "Allow"

    actions = sort([
      "acm:Describe*",
      "acm:Get*",
      "acm:List*",
      "apigateway:GET",
      "application-autoscaling:Describe*",
      "autoscaling:Describe*",
      "autoscaling-plans:Describe*",
      "autoscaling-plans:GetScalingPlanResourceForecastData",
      "athena:List*",
      "athena:Batch*",
      "athena:Get*",
      "batch:List*",
      "batch:Describe*",
      "cloudformation:Describe*",
      "cloudformation:Detect*",
      "cloudformation:Get*",
      "cloudformation:List*",
      "cloudformation:Estimate*",
      "cloudformation:Preview*",
      "cloudfront:Get*",
      "cloudfront:List*",
      "cloudsearch:Describe*",
      "cloudsearch:List*",
      "cloudwatch:Describe*",
      "cloudwatch:Get*",
      "cloudwatch:List*",
      "dax:BatchGetItem",
      "dax:Describe*",
      "dax:GetItem",
      "dax:ListTags",
      "dax:Query",
      "dax:Scan",
      "dlm:Get*",
      "dynamodb:BatchGet*",
      "dynamodb:Describe*",
      "dynamodb:Get*",
      "dynamodb:List*",
      "dynamodb:Query",
      "dynamodb:Scan",
      "ec2:Describe*",
      "ec2:Get*",
      "ec2:SearchTransitGatewayRoutes",
      "ec2messages:Get*",
      "ecr:BatchCheck*",
      "ecr:BatchGet*",
      "ecr:Describe*",
      "ecr:Get*",
      "ecr:List*",
      "ecs:Describe*",
      "ecs:List*",
      "eks:DescribeCluster",
      "eks:DescribeUpdates",
      "eks:ListClusters",
      "eks:ListUpdates",
      "elasticache:Describe*",
      "elasticache:List*",
      "elasticloadbalancing:Describe*",
      "elasticmapreduce:Describe*",
      "elasticmapreduce:List*",
      "elasticmapreduce:View*",
      "elastictranscoder:List*",
      "elastictranscoder:Read*",
      "es:Describe*",
      "es:List*",
      "es:Get*",
      "es:ESHttpGet",
      "es:ESHttpHead",
      "events:Describe*",
      "events:List*",
      "events:Test*",
      "firehose:Describe*",
      "firehose:List*",
      "glue:BatchGetPartition",
      "glue:GetCatalogImportStatus",
      "glue:GetClassifier",
      "glue:GetClassifiers",
      "glue:GetCrawler",
      "glue:GetCrawlers",
      "glue:GetCrawlerMetrics",
      "glue:GetDatabase",
      "glue:GetDatabases",
      "glue:GetDataCatalogEncryptionSettings",
      "glue:GetDataflowGraph",
      "glue:GetDevEndpoint",
      "glue:GetDevEndpoints",
      "glue:GetJob",
      "glue:GetJobs",
      "glue:GetJobRun",
      "glue:GetJobRuns",
      "glue:GetMapping",
      "glue:GetPartition",
      "glue:GetPartitions",
      "glue:GetPlan",
      "glue:GetResourcePolicy",
      "glue:GetSecurityConfiguration",
      "glue:GetSecurityConfigurations",
      "glue:GetTable",
      "glue:GetTables",
      "glue:GetTableVersion",
      "glue:GetTableVersions",
      "glue:GetTags",
      "glue:GetTrigger",
      "glue:GetTriggers",
      "glue:GetUserDefinedFunction",
      "glue:GetUserDefinedFunctions",
      "health:Describe*",
      "health:Get*",
      "health:List*",
      "iam:Generate*",
      "iam:Get*",
      "iam:List*",
      "iam:Simulate*",
      "importexport:Get*",
      "importexport:List*",
      "kafka:Describe*",
      "kafka:List*",
      "kafka:Get*",
      "kinesisanalytics:Describe*",
      "kinesisanalytics:Discover*",
      "kinesisanalytics:Get*",
      "kinesisanalytics:List*",
      "kinesisvideo:Describe*",
      "kinesisvideo:Get*",
      "kinesisvideo:List*",
      "kinesis:Describe*",
      "kinesis:Get*",
      "kinesis:List*",
      "kms:ListAliases",
      "lambda:List*",
      "lambda:Get*",
      "logs:Describe*",
      "logs:Get*",
      "logs:FilterLogEvents",
      "logs:ListTagsLogGroup",
      "logs:StartLiveTail",
      "logs:StartQuery",
      "logs:TestMetricFilter",
      "machinelearning:Describe*",
      "machinelearning:Get*",
      "mgh:Describe*",
      "mgh:List*",
      "mq:Describe*",
      "mq:List*",
      "organizations:Describe*",
      "organizations:List*",
      "personalize:Describe*",
      "personalize:Get*",
      "personalize:List*",
      "pi:DescribeDimensionKeys",
      "pi:GetResourceMetrics",
      "rekognition:CompareFaces",
      "rekognition:Detect*",
      "rekognition:List*",
      "rekognition:Search*",
      "rds:Describe*",
      "rds:List*",
      "rds:Download*",
      "redshift:Describe*",
      "redshift:GetReservedNodeExchangeOfferings",
      "redshift:View*",
      "resource-groups:Describe*",
      "resource-groups:Get*",
      "resource-groups:List*",
      "resource-groups:Search*",
      "robomaker:BatchDescribe*",
      "robomaker:Describe*",
      "robomaker:List*",
      "s3:Get*",
      "s3:List*",
      "s3:Head*",
      "sagemaker:Describe*",
      "sagemaker:GetSearchSuggestions",
      "sagemaker:List*",
      "sagemaker:Search",
      "sdb:Get*",
      "sdb:List*",
      "sdb:Select*",
      "serverlessrepo:List*",
      "serverlessrepo:Get*",
      "serverlessrepo:SearchApplications",
      "servicediscovery:Get*",
      "servicediscovery:List*",
      "sns:Get*",
      "sns:List*",
      "sns:Check*",
      "sqs:Get*",
      "sqs:List*",
      "sqs:Receive*",
      "ssm:Describe*",
      "ssm:Get*",
      "ssm:List*",
      "states:List*",
      "states:Describe*",
      "states:GetExecutionHistory",
      "sts:Get*",
      "tag:Get*",
      "xray:BatchGet*",
      "xray:Get*",
    ])

    resources = [
      "*",
    ]

    condition {
      test     = "BoolIfExists"
      variable = "aws:MultiFactorAuthPresent"

      values = [
        true
      ]
    }
  }

  statement {
    sid    = "AllowUsingKMSKeysViaLambdaService"
    effect = "Allow"
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
    ]
    condition {
      test     = "StringLike"
      variable = "kms:ViaService"
      values   = ["lambda.${var.region}.amazonaws.com"]
    }
    condition {
      test     = "StringEquals"
      variable = "aws:ResourceTag/application_family"
      values   = [var.application_family]
    }
    resources = ["arn:aws:kms:*:${data.aws_caller_identity.current.account_id}:*"]
  }
}

data "aws_iam_policy_document" "read_only" {
  count = var.require_mfa ? 0 : 1

  statement {
    sid = "AllowLimitedReadOnlyAccess"

    effect = "Allow"

    actions = sort([
      "acm:Describe*",
      "acm:Get*",
      "acm:List*",
      "apigateway:GET",
      "application-autoscaling:Describe*",
      "autoscaling:Describe*",
      "autoscaling-plans:Describe*",
      "autoscaling-plans:GetScalingPlanResourceForecastData",
      "athena:List*",
      "athena:Batch*",
      "athena:Get*",
      "batch:List*",
      "batch:Describe*",
      "cloudformation:Describe*",
      "cloudformation:Detect*",
      "cloudformation:Get*",
      "cloudformation:List*",
      "cloudformation:Estimate*",
      "cloudformation:Preview*",
      "cloudfront:Get*",
      "cloudfront:List*",
      "cloudsearch:Describe*",
      "cloudsearch:List*",
      "cloudwatch:Describe*",
      "cloudwatch:Get*",
      "cloudwatch:List*",
      "dax:BatchGetItem",
      "dax:Describe*",
      "dax:GetItem",
      "dax:ListTags",
      "dax:Query",
      "dax:Scan",
      "dlm:Get*",
      "dynamodb:BatchGet*",
      "dynamodb:Describe*",
      "dynamodb:Get*",
      "dynamodb:List*",
      "dynamodb:Query",
      "dynamodb:Scan",
      "ec2:Describe*",
      "ec2:Get*",
      "ec2:SearchTransitGatewayRoutes",
      "ec2messages:Get*",
      "ecr:BatchCheck*",
      "ecr:BatchGet*",
      "ecr:Describe*",
      "ecr:Get*",
      "ecr:List*",
      "ecs:Describe*",
      "ecs:List*",
      "eks:DescribeCluster",
      "eks:DescribeUpdates",
      "eks:ListClusters",
      "eks:ListUpdates",
      "elasticache:Describe*",
      "elasticache:List*",
      "elasticloadbalancing:Describe*",
      "elasticmapreduce:Describe*",
      "elasticmapreduce:List*",
      "elasticmapreduce:View*",
      "elastictranscoder:List*",
      "elastictranscoder:Read*",
      "es:Describe*",
      "es:List*",
      "es:Get*",
      "es:ESHttpGet",
      "es:ESHttpHead",
      "events:Describe*",
      "events:List*",
      "events:Test*",
      "firehose:Describe*",
      "firehose:List*",
      "glue:BatchGetPartition",
      "glue:GetCatalogImportStatus",
      "glue:GetClassifier",
      "glue:GetClassifiers",
      "glue:GetCrawler",
      "glue:GetCrawlers",
      "glue:GetCrawlerMetrics",
      "glue:GetDatabase",
      "glue:GetDatabases",
      "glue:GetDataCatalogEncryptionSettings",
      "glue:GetDataflowGraph",
      "glue:GetDevEndpoint",
      "glue:GetDevEndpoints",
      "glue:GetJob",
      "glue:GetJobs",
      "glue:GetJobRun",
      "glue:GetJobRuns",
      "glue:GetMapping",
      "glue:GetPartition",
      "glue:GetPartitions",
      "glue:GetPlan",
      "glue:GetResourcePolicy",
      "glue:GetSecurityConfiguration",
      "glue:GetSecurityConfigurations",
      "glue:GetTable",
      "glue:GetTables",
      "glue:GetTableVersion",
      "glue:GetTableVersions",
      "glue:GetTags",
      "glue:GetTrigger",
      "glue:GetTriggers",
      "glue:GetUserDefinedFunction",
      "glue:GetUserDefinedFunctions",
      "health:Describe*",
      "health:Get*",
      "health:List*",
      "iam:Generate*",
      "iam:Get*",
      "iam:List*",
      "iam:Simulate*",
      "importexport:Get*",
      "importexport:List*",
      "kafka:Describe*",
      "kafka:List*",
      "kafka:Get*",
      "kinesisanalytics:Describe*",
      "kinesisanalytics:Discover*",
      "kinesisanalytics:Get*",
      "kinesisanalytics:List*",
      "kinesisvideo:Describe*",
      "kinesisvideo:Get*",
      "kinesisvideo:List*",
      "kinesis:Describe*",
      "kinesis:Get*",
      "kinesis:List*",
      "kms:ListAliases",
      "lambda:List*",
      "lambda:Get*",
      "logs:Describe*",
      "logs:Get*",
      "logs:FilterLogEvents",
      "logs:ListTagsLogGroup",
      "logs:StartLiveTail",
      "logs:StartQuery",
      "logs:TestMetricFilter",
      "machinelearning:Describe*",
      "machinelearning:Get*",
      "mgh:Describe*",
      "mgh:List*",
      "mq:Describe*",
      "mq:List*",
      "organizations:Describe*",
      "organizations:List*",
      "personalize:Describe*",
      "personalize:Get*",
      "personalize:List*",
      "pi:DescribeDimensionKeys",
      "pi:GetResourceMetrics",
      "rekognition:CompareFaces",
      "rekognition:Detect*",
      "rekognition:List*",
      "rekognition:Search*",
      "rds:Describe*",
      "rds:List*",
      "rds:Download*",
      "redshift:Describe*",
      "redshift:GetReservedNodeExchangeOfferings",
      "redshift:View*",
      "resource-groups:Describe*",
      "resource-groups:Get*",
      "resource-groups:List*",
      "resource-groups:Search*",
      "robomaker:BatchDescribe*",
      "robomaker:Describe*",
      "robomaker:List*",
      "s3:Get*",
      "s3:List*",
      "s3:Head*",
      "sagemaker:Describe*",
      "sagemaker:GetSearchSuggestions",
      "sagemaker:List*",
      "sagemaker:Search",
      "sdb:Get*",
      "sdb:List*",
      "sdb:Select*",
      "serverlessrepo:List*",
      "serverlessrepo:Get*",
      "serverlessrepo:SearchApplications",
      "servicediscovery:Get*",
      "servicediscovery:List*",
      "sns:Get*",
      "sns:List*",
      "sns:Check*",
      "sqs:Get*",
      "sqs:List*",
      "sqs:Receive*",
      "ssm:Describe*",
      "ssm:Get*",
      "ssm:List*",
      "states:List*",
      "states:Describe*",
      "states:GetExecutionHistory",
      "sts:Get*",
      "tag:Get*",
      "xray:BatchGet*",
      "xray:Get*",
    ])

    resources = [
      "*",
    ]
  }

  statement {
    sid    = "AllowUsingKMSKeysViaLambdaService"
    effect = "Allow"
    actions = [
      "kms:Decrypt",
      "kms:DescribeKey",
    ]
    condition {
      test     = "StringLike"
      variable = "kms:ViaService"
      values   = ["lambda.${var.region}.amazonaws.com"]
    }
    condition {
      test     = "StringEquals"
      variable = "aws:ResourceTag/application_family"
      values   = [var.application_family]
    }
    resources = ["arn:aws:kms:*:${data.aws_caller_identity.current.account_id}:*"]
  }
}
