######################
# Access keys
#
# For rotation purposes, there are two of these. Delete the oldest one, 
# add a new one (with a higher version number), and then update the output
#
# Possible futue improvement:
# We could specify a pgp_key attribute, and then the secret will be encrypted
# in both the state file and in the output. If we used the salt PGP key,
# no user would ever have to see the secret key.
locals {
  # The user in this file will only be created for Commercial C2
  is_commercial = var.aws_partition == "aws-us-gov" ? false : true
  is_c2         = contains(["045312110490", "816914342178" ], var.aws_account_id)
  user_count    = local.is_commercial && local.is_c2 ? 1 : 0
}

resource "aws_iam_access_key" "salt-master-v0" {
  count = local.user_count
  user = aws_iam_user.salt-master[count.index].name
}

resource "aws_iam_access_key" "salt-master-v1" {
  count = local.user_count
  user = aws_iam_user.salt-master[count.index].name
}

output access_keys {
  # Only output the keys if there _are_ keys
  value = local.user_count == 0 ? null : {
      "current" = { 
        "aws_access_key_id": aws_iam_access_key.salt-master-v1[0].id
        "aws_secret_access_key": aws_iam_access_key.salt-master-v1[0].secret
      },
      "previous" = {
        "aws_access_key_id": aws_iam_access_key.salt-master-v0[0].id
        "aws_secret_access_key": aws_iam_access_key.salt-master-v0[0].secret
      }
    }
  sensitive = true
}

######################
# The policy is attached to both the user and the instance profile
data "aws_iam_policy_document" "salt_master_policy_doc" {
  statement {
    sid    = "AllowSaltSecretsCommunication"
    effect = "Allow"

    actions = [
      "secretsmanager:GetResourcePolicy",
      "secretsmanager:GetSecretValue",
      "secretsmanager:DescribeSecret",
      "secretsmanager:ListSecretVersionIds"
    ]

    resources = [
      "arn:${var.aws_partition}:secretsmanager:*:*:secret:saltmaster/*"
    ]
  }

  statement {
    sid    = "AllowAssumeRole"
    effect = "Allow"

    actions = [
      "sts:AssumeRole"
    ]

    resources = [
      "arn:${var.aws_partition}:iam::*:role/service/salt-master-inventory-role",

      # This may not belong here.  This is related to the Neustar GeoIP support.
      # The cron job that runs on the salt master to download Neustar files from
      # their sftp server and put them on S3 needs to be able to assume this role
      # both in commercial and govcloud, as we have systems in both partitions that
      # need the S3 bucket updated with latest geoip files.  This covers the case
      # of a govcloud salt-master pushing files into commercial S3.
      "arn:${var.aws_partition}:iam::*:role/service/afsxdr-binaries_writers",
    ]
  }
}

resource "aws_iam_policy" "salt-master" {
  count       = local.user_count
  name        = "salt_master_sm"
  path        = "/"
  policy      = data.aws_iam_policy_document.salt_master_policy_doc.json
}

######################
# the user
#
# Note: CIS requires that policies _NOT_ be directly attached to a user. Users must
# be members of groups, and those groups can have policies.
resource "aws_iam_user" "salt-master" {
  count = local.user_count
  name = "salt-master"
  path = "/instance/"

  tags = merge(var.standard_tags, var.tags)
}

resource "aws_iam_group" "salt-master" {
  count = local.user_count
  name = "salt-master"
  path = "/instance/"
}

resource "aws_iam_user_group_membership" "salt-master" {
  count = local.user_count
  user = aws_iam_user.salt-master[count.index].name

  groups = [ aws_iam_group.salt-master[count.index].name ]
}

resource "aws_iam_group_policy_attachment" "salt-master-group" {
  count = local.user_count
  group      = aws_iam_group.salt-master[count.index].name
  policy_arn = aws_iam_policy.salt-master[count.index].arn
}
