locals {
  qa_actions_list = 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*",
    "batch:SubmitJob",
    "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*",
    "dms:Describe*",
    "dms:List*",
    "dms:StartReplicationTask",
    "dms:StopReplicationTask",
    "devicefarm:List*",
    "devicefarm:Get*",
    "devicefarm:Stop*",
    "devicefarm:Update*",
    "devicefarm:CreateUpload",
    "devicefarm:CreateNetwork*",
    "devicefarm:CreateDevice*",
    "devicefarm:CreateInstance*",
    "devicefarm:DeleteNetwork*",
    "devicefarm:DeleteDevice*",
    "devicefarm:DeleteInstance*",
    "devicefarm:ScheduleRun",
    "dynamodb:BatchGet*",
    "dynamodb:Describe*",
    "dynamodb:Get*",
    "dynamodb:List*",
    "dynamodb:Query",
    "dynamodb:Scan",
    "dynamodb:BatchGet*",
    "dynamodb:BatchWrite*",
    "dynamodb:Delete*",
    "dynamodb:Update*",
    "dynamodb:PutItem",
    "ec2:Describe*",
    "ec2:Get*",
    "ec2:SearchTransitGatewayRoutes",
    "ec2messages:Get*",
    "ecr:BatchCheck*",
    "ecr:BatchGet*",
    "ecr:Describe*",
    "ecr:Get*",
    "ecr:List*",
    "ecs:Describe*",
    "ecs:List*",
    "ecs:StartTask",
    "ecs:StopTask",
    "ecs:RunTask",
    "eks:DescribeCluster",
    "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:DisableRule",
    "events:EnableRule",
    "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*",
    "iam:Generate*",
    "iam:Get*",
    "iam:List*",
    "iam:Simulate*",
    "iam:PassRole",
    "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*",
    "kinesis:PutRecord",
    "kinesis:PutRecords",
    "kms:ListAliases",
    "lambda:List*",
    "lambda:Get*",
    "lambda:InvokeFunction",
    "lambda:UpdateFunctionConfiguration",
    "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:Get*",
    "resource-groups:List*",
    "resource-groups:Search*",
    "robomaker:BatchDescribe*",
    "robomaker:Describe*",
    "robomaker:List*",
    "s3:Get*",
    "s3:List*",
    "s3:PutObject*",
    "s3:DeleteObject*",
    "s3:Restore*",
    "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",
    "states:StartExecution",
    "states:StopExecution",
    "states:SendTask*",
    "sts:Get*",
    "tag:Get*",
    "xray:BatchGet*",
    "xray:Get*",
  ])
}
data "aws_iam_policy_document" "qa_user_mfa" {
  count = var.require_mfa ? 1 : 0

  statement {
    sid = "AllowLimitedReadOnlyAccessWithSomeExtraPermissions"

    effect  = "Allow"
    actions = local.qa_actions_list

    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" "qa_user" {
  count = var.require_mfa ? 0 : 1

  statement {
    sid = "AllowLimitedReadOnlyAccessWithSomeExtraPermissions"

    effect  = "Allow"
    actions = local.qa_actions_list

    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}:*"]
  }
}
