user.tf 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. ######################
  2. # Access keys
  3. #
  4. # For rotation purposes, there are two of these. Delete the oldest one,
  5. # add a new one (with a higher version number), and then update the output
  6. #
  7. # Possible futue improvement:
  8. # We could specify a pgp_key attribute, and then the secret will be encrypted
  9. # in both the state file and in the output. If we used the salt PGP key,
  10. # no user would ever have to see the secret key.
  11. locals {
  12. # The user in this file will only be created for Commercial C2
  13. is_commercial = var.aws_partition == "aws-us-gov" ? false : true
  14. is_c2 = contains(["045312110490", "816914342178"], var.aws_account_id)
  15. user_count = local.is_commercial && local.is_c2 ? 1 : 0
  16. }
  17. resource "aws_iam_access_key" "salt-master-v2" {
  18. count = local.user_count
  19. user = aws_iam_user.salt-master[count.index].name
  20. }
  21. resource "aws_iam_access_key" "salt-master-v3" {
  22. count = local.user_count
  23. user = aws_iam_user.salt-master[count.index].name
  24. }
  25. output "access_keys" {
  26. # Only output the keys if there _are_ keys
  27. value = local.user_count == 0 ? null : {
  28. "current" = {
  29. "aws_access_key_id" : aws_iam_access_key.salt-master-v3[0].id
  30. "aws_secret_access_key" : aws_iam_access_key.salt-master-v3[0].secret
  31. },
  32. "previous" = {
  33. "aws_access_key_id" : aws_iam_access_key.salt-master-v2[0].id
  34. "aws_secret_access_key" : aws_iam_access_key.salt-master-v2[0].secret
  35. }
  36. }
  37. sensitive = true
  38. }
  39. ######################
  40. # The policy is attached to both the user and the instance profile
  41. data "aws_iam_policy_document" "salt_master_policy_doc" {
  42. statement {
  43. sid = "AllowSaltSecretsCommunication"
  44. effect = "Allow"
  45. actions = [
  46. "secretsmanager:GetResourcePolicy",
  47. "secretsmanager:GetSecretValue",
  48. "secretsmanager:DescribeSecret",
  49. "secretsmanager:ListSecretVersionIds"
  50. ]
  51. # tfsec:ignore:aws-iam-no-policy-wildcards This is read-only access
  52. resources = [
  53. "arn:${var.aws_partition}:secretsmanager:*:*:secret:saltmaster/*"
  54. ]
  55. }
  56. statement {
  57. sid = "AllowAssumeRole"
  58. effect = "Allow"
  59. actions = [
  60. "sts:AssumeRole"
  61. ]
  62. # tfsec:ignore:aws-iam-no-policy-wildcards This is read-only access
  63. resources = [
  64. "arn:${var.aws_partition}:iam::*:role/service/salt-master-inventory-role",
  65. # This may not belong here. This is related to the Neustar GeoIP support.
  66. # The cron job that runs on the salt master to download Neustar files from
  67. # their sftp server and put them on S3 needs to be able to assume this role
  68. # both in commercial and govcloud, as we have systems in both partitions that
  69. # need the S3 bucket updated with latest geoip files. This covers the case
  70. # of a govcloud salt-master pushing files into commercial S3.
  71. "arn:${var.aws_partition}:iam::*:role/service/afsxdr-binaries_writers",
  72. ]
  73. }
  74. }
  75. resource "aws_iam_policy" "salt-master" {
  76. count = local.user_count
  77. name = "salt_master_sm"
  78. path = "/"
  79. policy = data.aws_iam_policy_document.salt_master_policy_doc.json
  80. }
  81. ######################
  82. # the user
  83. #
  84. # Note: CIS requires that policies _NOT_ be directly attached to a user. Users must
  85. # be members of groups, and those groups can have policies.
  86. resource "aws_iam_user" "salt-master" {
  87. count = local.user_count
  88. name = "salt-master"
  89. path = "/instance/"
  90. tags = merge(local.standard_tags, var.tags)
  91. }
  92. # tfsec:ignore:aws-iam-enforce-mfa No MFA for service account
  93. resource "aws_iam_group" "salt-master" {
  94. count = local.user_count
  95. name = "salt-master"
  96. path = "/instance/"
  97. }
  98. resource "aws_iam_user_group_membership" "salt-master" {
  99. count = local.user_count
  100. user = aws_iam_user.salt-master[count.index].name
  101. groups = [aws_iam_group.salt-master[count.index].name]
  102. }
  103. resource "aws_iam_group_policy_attachment" "salt-master-group" {
  104. count = local.user_count
  105. group = aws_iam_group.salt-master[count.index].name
  106. policy_arn = aws_iam_policy.salt-master[count.index].arn
  107. }