diff --git a/CHANGELOG.md b/CHANGELOG.md index 6454e96..e812628 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,3 +25,6 @@ - iam-general-policies - add `managed_policies` for AWS managed policy references - change `policies` to `custom_policies` + +* v1.6.0 -- 20210302 + - module: iam-cloud-admin diff --git a/common/version.tf b/common/version.tf index 34b1108..2cc7061 100644 --- a/common/version.tf +++ b/common/version.tf @@ -1,3 +1,3 @@ locals { - _module_version = "1.5.1" + _module_version = "1.6.0" } diff --git a/iam-cloud-admin/README.md b/iam-cloud-admin/README.md new file mode 100644 index 0000000..e73c37a --- /dev/null +++ b/iam-cloud-admin/README.md @@ -0,0 +1,87 @@ +# aws-inf-setup :: s3-flow-logs + +This set up the needed components for S3 VPC flow log bucket. Only one flow log bucket is +needed + +* S3 bucket +* S3 bucket objects (key prefixes, aka "directories") +* S3 bucket policy + +# Usage +Here is a simple example, the one most commonly expected to be used. + +```hcl +module "flowlogs" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//s3-flow-flowlogs" +} +``` + +This one can be used if you need to customize stuff, though really, the defaults are all built +for a reason, and deployment code (i.e., Ansible) will expect these defaults to be used in +variable file generation. + +```hcl +module "flowlogs_full" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//s3-flow-flowlogs" + + # optional + account_alias = "do2-govcloud" + bucket_name = "inf-flowlogs-123456789012" + + # flowlogs is generally not needed and not recommended + component_tags = { + "s3" = { + "SpecialTag1" = "something" + "SpecialTag2" = "somethingElse" + } + } +} +``` + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| aws | n/a | + +## Modules + +No Modules. + +## Resources + +| Name | +|------| +| [aws_arn](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | +| [aws_caller_identity](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | +| [aws_iam_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | +| [aws_iam_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | +| [aws_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | +| [aws_region](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | +| [aws_s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | +| [aws_s3_bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | +| [aws_s3_bucket_public_access_block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| account\_alias | AWS Account Alias | `string` | `""` | no | +| account\_id | AWS Account ID (default will pull from current user) | `string` | `""` | no | +| bucket\_name | VPC Flow Logs S3 bucket name | `string` | `""` | no | +| bucket\_name\_prefix | VPC Flow Logs S3 bucket prefix, prepended to the AWS account ID to make the bucket name. | `string` | `"inf-flowlogs"` | no | +| component\_tags | Additional tags for Components (s3, kms, ddb) | `map(map(string))` |
{
"ddb": {},
"kms": {},
"s3": {}
} | no |
+| override\_prefixes | Override built-in prefixes by component (efs, s3, ebs, kms, role, policy, security-group). This should be used primarily for common infrastructure things | `map(string)` | `{}` | no |
+| tags | AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data\_safeguard field for such things. | `map(string)` | `{}` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| flowlogs\_bucket\_arn | VPC Flow Logs S3 bucket ARN |
+| flowlogs\_bucket\_id | VPC Flow Logs S3 bucket ID |
+| policy\_assume\_ec2 | Policy for assume for ec2 |
diff --git a/iam-cloud-admin/data.tf b/iam-cloud-admin/data.tf
new file mode 120000
index 0000000..995624d
--- /dev/null
+++ b/iam-cloud-admin/data.tf
@@ -0,0 +1 @@
+../common/data.tf
\ No newline at end of file
diff --git a/iam-cloud-admin/defaults.tf b/iam-cloud-admin/defaults.tf
new file mode 120000
index 0000000..a5556ac
--- /dev/null
+++ b/iam-cloud-admin/defaults.tf
@@ -0,0 +1 @@
+../common/defaults.tf
\ No newline at end of file
diff --git a/iam-cloud-admin/inf-roles.tf b/iam-cloud-admin/inf-roles.tf
new file mode 100644
index 0000000..278d2fa
--- /dev/null
+++ b/iam-cloud-admin/inf-roles.tf
@@ -0,0 +1,40 @@
+
+#resource "aws_iam_role" "inf-cloud-admin" {
+# name = "r-inf-cloud-admin"
+# description = "r-inf-cloud-admin role for CSVD admins"
+#
+# assume_role_policy = data.aws_iam_policy_document.inf-saml_assume.json
+# force_detach_policies = false
+# max_session_duration = 3600
+# }
+# imported
+
+resource "aws_iam_role" "inf-cloud-admin" {
+ assume_role_policy = jsonencode(
+ {
+ Statement = [
+ {
+ Action = "sts:AssumeRoleWithSAML"
+ Condition = {
+ StringEquals = {
+ "SAML:aud" = "https://signin.amazonaws-us-gov.com/saml"
+ }
+ }
+ Effect = "Allow"
+ Principal = {
+ Federated = "arn:aws-us-gov:iam::107742151971:saml-provider/Census_TCO_IDMS"
+ }
+ },
+ ]
+ Version = "2012-10-17"
+ }
+ )
+ description = "r-inf-cloud-admin role for CSVD admins"
+ force_detach_policies = false
+ max_session_duration = 3600
+ name = "r-inf-cloud-admin"
+ tags = {
+ "Creator" = "ashle001"
+ "Name" = "r-inf-cloud-admin"
+ }
+}
diff --git a/iam-cloud-admin/main.tf b/iam-cloud-admin/main.tf
new file mode 100644
index 0000000..5ef71a5
--- /dev/null
+++ b/iam-cloud-admin/main.tf
@@ -0,0 +1,110 @@
+/*
+* # aws-inf-setup :: s3-flow-logs
+*
+* This set up the needed components for S3 VPC flow log bucket. Only one flow log bucket is
+* needed
+*
+* * S3 bucket
+* * S3 bucket objects (key prefixes, aka "directories")
+* * S3 bucket policy
+*
+* # Usage
+* Here is a simple example, the one most commonly expected to be used.
+*
+* ```hcl
+* module "flowlogs" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//s3-flow-flowlogs"
+* }
+* ```
+*
+* This one can be used if you need to customize stuff, though really, the defaults are all built
+* for a reason, and deployment code (i.e., Ansible) will expect these defaults to be used in
+* variable file generation.
+*
+* ```hcl
+* module "flowlogs_full" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//s3-flow-flowlogs"
+*
+* # optional
+* account_alias = "do2-govcloud"
+* bucket_name = "inf-flowlogs-123456789012"
+*
+* # flowlogs is generally not needed and not recommended
+* component_tags = {
+* "s3" = {
+* "SpecialTag1" = "something"
+* "SpecialTag2" = "somethingElse"
+* }
+* }
+* }
+* ```
+*/
+
+locals {
+ account_id = var.account_id != "" ? var.account_id : data.aws_caller_identity.current.account_id
+ flowlogs_region = data.aws_region.current.name
+ account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew"
+
+ bucket_name = var.bucket_name != "" ? var.bucket_name : format("%v-%v-%v", var.bucket_name_prefix, local.account_id, local.flowlogs_region)
+
+ base_tags = {
+ "Organization" = "census:aditcio:csvd"
+ "boc:tf_module_version" = local._module_version
+ "boc:created_by" = "terraform"
+ }
+}
+
+#---
+# s3
+#---
+resource "aws_s3_bucket" "flowlogs" {
+ bucket = local.bucket_name
+ acl = "log-delivery-write"
+
+ # need to create the inf_ key used for infrastucture things like
+ # vpc flow, cloudtrail, config, sns, sqs
+
+ server_side_encryption_configuration {
+ rule {
+ apply_server_side_encryption_by_default {
+ # kms_master_key_id = local.inf_key_arn
+ sse_algorithm = "aws:kms"
+ }
+ }
+ }
+
+ versioning {
+ enabled = false
+ }
+
+ lifecycle {
+ prevent_destroy = true
+ }
+
+ # probably want some migration of old data to some other location
+ # like glacier
+
+ tags = merge(
+ var.tags,
+ local.base_tags,
+ lookup(var.component_tags, "s3", {}),
+ map("Name", local.bucket_name),
+ )
+
+ provisioner "local-exec" {
+ command = "sleep 30"
+ }
+}
+
+resource "aws_s3_bucket_public_access_block" "flowlogs" {
+ bucket = aws_s3_bucket.flowlogs.id
+ block_public_acls = true
+ block_public_policy = true
+ ignore_public_acls = true
+ restrict_public_buckets = true
+}
+
+resource "aws_s3_bucket_policy" "flowlogs" {
+ bucket = aws_s3_bucket.flowlogs.id
+ policy = data.aws_iam_policy_document.flowlogs_s3.json
+}
diff --git a/iam-cloud-admin/outputs.tf b/iam-cloud-admin/outputs.tf
new file mode 100644
index 0000000..cc57cc2
--- /dev/null
+++ b/iam-cloud-admin/outputs.tf
@@ -0,0 +1,9 @@
+output "flowlogs_bucket_id" {
+ description = "VPC Flow Logs S3 bucket ID"
+ value = aws_s3_bucket.flowlogs.id
+}
+
+output "flowlogs_bucket_arn" {
+ description = "VPC Flow Logs S3 bucket ARN"
+ value = aws_s3_bucket.flowlogs.arn
+}
diff --git a/iam-cloud-admin/policies.sts.tf b/iam-cloud-admin/policies.sts.tf
new file mode 100644
index 0000000..46e7375
--- /dev/null
+++ b/iam-cloud-admin/policies.sts.tf
@@ -0,0 +1,21 @@
+#----
+# STS: ec2 assume
+#---
+data "aws_iam_policy_document" "ec2_assume" {
+ statement {
+ sid = "AWSEC2AssumeRole"
+ effect = "Allow"
+ actions = ["sts:AssumeRole"]
+
+ principals {
+ type = "Service"
+ identifiers = ["ec2.amazonaws.com"]
+ }
+ }
+}
+
+output "policy_assume_ec2" {
+ description = "Policy for assume for ec2"
+ value = data.aws_iam_policy_document.ec2_assume.json
+}
+
diff --git a/iam-cloud-admin/policies.tf b/iam-cloud-admin/policies.tf
new file mode 100644
index 0000000..111a21a
--- /dev/null
+++ b/iam-cloud-admin/policies.tf
@@ -0,0 +1,161 @@
+## #---
+## # for auditing
+## # from prowler: https://github.com/toniblyx/prowler
+## #---
+## data "aws_iam_policy_document" "inf-security-audit" {
+## statement {
+## sid = "AdditionalSecurityAuditpermissions"
+## effect = "Allow"
+## actions = [ "support:DescribeTrustedAdvisorChecks" ]
+## resources = [ "*", ]
+## }
+## }
+## resource "aws_iam_policy" "inf-security-audit" {
+## name = "p-inf-security-audit"
+## path = "/"
+## description = "Policy for Security Auditing"
+## policy = "${data.aws_iam_policy_document.inf-security-audit.json}"
+## }
+##
+## data "aws_iam_policy" "aws-managed-security-audit" {
+## arn = "arn:${var.aws_arn_partition}:iam::aws:policy/SecurityAudit"
+## }
+##
+## locals {
+## inf-security-audit-policies = [ "${data.aws_iam_policy.aws-managed-security-audit.arn}","$(aws_iam_policy.inf-security-audit.arn}" ]
+## }
+##
+## resource "aws_iam_group_policy_attachment" "inf-security-audit" {
+## count = "${length(local.inf-security-audit-policies)}"
+## group = "${aws_iam_group.inf-security-audit.name}"
+## policy_arn = "${element(local.inf-security-audit-policies,count.index)}"
+## }
+##
+## # really, want to do this
+## # module security_audit
+## # source modules/boc-aws-security-audit
+## # common_name = name suite of things (like, inf-security-audit, and other things created from it)
+## # group_name = default of g-$common_name
+## # policy_name = default of p-$common_name
+## # users = [array of service account users, if not specified, creates as s-$common_name
+##
+#---
+# to allow self managed access keys, or access keys plus passwords
+#---
+data "aws_iam_policy_document" "inf-manage-access-keys" {
+ statement {
+ sid = "ManageOwnAccessKeys"
+ effect = "Allow"
+ resources = ["arn:${data.aws_arn.current.partition}:iam::*:user/$${aws:username}"]
+ actions = [
+ "iam:CreateAccessKey",
+ "iam:DeleteAccessKey",
+ "iam:GetAccessKeyLastUsed",
+ "iam:GetUser",
+ "iam:ListAccessKeys",
+ "iam:UpdateAccessKey",
+ ]
+ }
+}
+
+data "aws_iam_policy_document" "inf-manage-credentials" {
+ statement {
+ sid = "ManageOwnAccessKeys"
+ effect = "Allow"
+ resources = ["arn:${data.aws_arn.current.partition}:iam::*:user/$${aws:username}"]
+ actions = [
+ "iam:CreateAccessKey",
+ "iam:DeleteAccessKey",
+ "iam:GetAccessKeyLastUsed",
+ "iam:GetUser",
+ "iam:ListAccessKeys",
+ "iam:UpdateAccessKey",
+ ]
+ }
+ statement {
+ sid = "ManageOwnPasswordGet"
+ effect = "Allow"
+ resources = ["*"]
+ actions = ["iam:GetAccountPasswordPolicy"]
+ }
+ statement {
+ sid = "ManageOwnPasswordChange"
+ effect = "Allow"
+ resources = ["arn:${data.aws_arn.current.partition}:iam::*:user/$${aws:username}"]
+ actions = ["iam:ChangePassword"]
+ }
+}
+
+resource "aws_iam_policy" "inf-manage-access-keys" {
+ name = "p-inf-manage-access-keys"
+ path = "/"
+ description = "Manage own access keys"
+ policy = data.aws_iam_policy_document.inf-manage-access-keys.json
+}
+
+resource "aws_iam_policy" "inf-manage-credentials" {
+ name = "p-inf-manage-credentials"
+ path = "/"
+ description = "Manage own access keys and password"
+ policy = data.aws_iam_policy_document.inf-manage-credentials.json
+}
+
+
+#---
+# access policy for inf key
+#---
+data "aws_iam_policy_document" "inf_kms_access" {
+ policy_id = "inf_kms_access"
+ statement {
+ sid = "IAMPermissionsAccessKMSManagement"
+ effect = "Allow"
+ actions = ["kms:*"]
+ resources = ["*"]
+ principals {
+ type = "AWS"
+ identifiers = [
+ # data.aws_caller_identity.current.arn,
+ aws_iam_role.inf-cloud-admin.arn,
+ "arn:${data.aws_arn.current.partition}:iam::${var.account_id}:root",
+ ]
+ }
+ }
+ statement {
+ sid = "IAMPermissionsAccessKMSFlowlogs"
+ effect = "Allow"
+ actions = [
+ "kms:Encrypt",
+ "kms:Decrypt",
+ "kms:ReEncrypt*",
+ "kms:GenerateDataKey*",
+ "kms:DescribeKey",
+ ]
+ resources = ["*"]
+ principals {
+ type = "Service"
+ identifiers = ["delivery.logs.amazonaws.com"]
+ }
+ }
+}
+
+#---
+# deny access to billing
+#---
+resource "aws_iam_policy" "deny_billing" {
+ name = "p-inf-deny-billing"
+ path = "/"
+ description = "Policy to deny access to billing and cost allocation"
+ policy = data.aws_iam_policy_document.deny_billing.json
+}
+
+data "aws_iam_policy_document" "deny_billing" {
+ statement {
+ sid = "DenyCensusBillingAndCostManagement"
+ effect = "Deny"
+ resources = ["*"]
+
+ actions = [
+ "aws-portal:*",
+ ]
+ }
+}
diff --git a/iam-cloud-admin/policy_data.tf b/iam-cloud-admin/policy_data.tf
new file mode 100644
index 0000000..f7725bc
--- /dev/null
+++ b/iam-cloud-admin/policy_data.tf
@@ -0,0 +1,162 @@
+
+## #---
+## # for auditing
+## # from prowler: https://github.com/toniblyx/prowler
+## #---
+## data "aws_iam_policy_document" "inf-security-audit" {
+## statement {
+## sid = "AdditionalSecurityAuditpermissions"
+## effect = "Allow"
+## actions = [ "support:DescribeTrustedAdvisorChecks" ]
+## resources = [ "*", ]
+## }
+## }
+## resource "aws_iam_policy" "inf-security-audit" {
+## name = "p-inf-security-audit"
+## path = "/"
+## description = "Policy for Security Auditing"
+## policy = "${data.aws_iam_policy_document.inf-security-audit.json}"
+## }
+##
+## data "aws_iam_policy" "aws-managed-security-audit" {
+## arn = "arn:${var.aws_arn_partition}:iam::aws:policy/SecurityAudit"
+## }
+##
+## locals {
+## inf-security-audit-policies = [ "${data.aws_iam_policy.aws-managed-security-audit.arn}","$(aws_iam_policy.inf-security-audit.arn}" ]
+## }
+##
+## resource "aws_iam_group_policy_attachment" "inf-security-audit" {
+## count = "${length(local.inf-security-audit-policies)}"
+## group = "${aws_iam_group.inf-security-audit.name}"
+## policy_arn = "${element(local.inf-security-audit-policies,count.index)}"
+## }
+##
+## # really, want to do this
+## # module security_audit
+## # source modules/boc-aws-security-audit
+## # common_name = name suite of things (like, inf-security-audit, and other things created from it)
+## # group_name = default of g-$common_name
+## # policy_name = default of p-$common_name
+## # users = [array of service account users, if not specified, creates as s-$common_name
+##
+#---
+# to allow self managed access keys, or access keys plus passwords
+#---
+data "aws_iam_policy_document" "inf-manage-access-keys" {
+ statement {
+ sid = "ManageOwnAccessKeys"
+ effect = "Allow"
+ resources = ["arn:${data.aws_arn.current.partition}:iam::*:user/$${aws:username}"]
+ actions = [
+ "iam:CreateAccessKey",
+ "iam:DeleteAccessKey",
+ "iam:GetAccessKeyLastUsed",
+ "iam:GetUser",
+ "iam:ListAccessKeys",
+ "iam:UpdateAccessKey",
+ ]
+ }
+}
+
+data "aws_iam_policy_document" "inf-manage-credentials" {
+ statement {
+ sid = "ManageOwnAccessKeys"
+ effect = "Allow"
+ resources = ["arn:${data.aws_arn.current.partition}:iam::*:user/$${aws:username}"]
+ actions = [
+ "iam:CreateAccessKey",
+ "iam:DeleteAccessKey",
+ "iam:GetAccessKeyLastUsed",
+ "iam:GetUser",
+ "iam:ListAccessKeys",
+ "iam:UpdateAccessKey",
+ ]
+ }
+ statement {
+ sid = "ManageOwnPasswordGet"
+ effect = "Allow"
+ resources = ["*"]
+ actions = ["iam:GetAccountPasswordPolicy"]
+ }
+ statement {
+ sid = "ManageOwnPasswordChange"
+ effect = "Allow"
+ resources = ["arn:${data.aws_arn.current.partition}:iam::*:user/$${aws:username}"]
+ actions = ["iam:ChangePassword"]
+ }
+}
+
+resource "aws_iam_policy" "inf-manage-access-keys" {
+ name = "p-inf-manage-access-keys"
+ path = "/"
+ description = "Manage own access keys"
+ policy = data.aws_iam_policy_document.inf-manage-access-keys.json
+}
+
+resource "aws_iam_policy" "inf-manage-credentials" {
+ name = "p-inf-manage-credentials"
+ path = "/"
+ description = "Manage own access keys and password"
+ policy = data.aws_iam_policy_document.inf-manage-credentials.json
+}
+
+
+#---
+# access policy for inf key
+#---
+data "aws_iam_policy_document" "inf_kms_access" {
+ policy_id = "inf_kms_access"
+ statement {
+ sid = "IAMPermissionsAccessKMSManagement"
+ effect = "Allow"
+ actions = ["kms:*"]
+ resources = ["*"]
+ principals {
+ type = "AWS"
+ identifiers = [
+ # data.aws_caller_identity.current.arn,
+ aws_iam_role.inf-cloud-admin.arn,
+ "arn:${data.aws_arn.current.partition}:iam::${var.account_id}:root",
+ ]
+ }
+ }
+ statement {
+ sid = "IAMPermissionsAccessKMSFlowlogs"
+ effect = "Allow"
+ actions = [
+ "kms:Encrypt",
+ "kms:Decrypt",
+ "kms:ReEncrypt*",
+ "kms:GenerateDataKey*",
+ "kms:DescribeKey",
+ ]
+ resources = ["*"]
+ principals {
+ type = "Service"
+ identifiers = ["delivery.logs.amazonaws.com"]
+ }
+ }
+}
+
+#---
+# deny access to billing
+#---
+resource "aws_iam_policy" "deny_billing" {
+ name = "p-inf-deny-billing"
+ path = "/"
+ description = "Policy to deny access to billing and cost allocation"
+ policy = data.aws_iam_policy_document.deny_billing.json
+}
+
+data "aws_iam_policy_document" "deny_billing" {
+ statement {
+ sid = "DenyCensusBillingAndCostManagement"
+ effect = "Deny"
+ resources = ["*"]
+
+ actions = [
+ "aws-portal:*",
+ ]
+ }
+}
diff --git a/iam-cloud-admin/prefixes.tf b/iam-cloud-admin/prefixes.tf
new file mode 120000
index 0000000..7e265d5
--- /dev/null
+++ b/iam-cloud-admin/prefixes.tf
@@ -0,0 +1 @@
+../common/prefixes.tf
\ No newline at end of file
diff --git a/iam-cloud-admin/variables.common.tf b/iam-cloud-admin/variables.common.tf
new file mode 120000
index 0000000..7439ed8
--- /dev/null
+++ b/iam-cloud-admin/variables.common.tf
@@ -0,0 +1 @@
+../common/variables.common.tf
\ No newline at end of file
diff --git a/iam-cloud-admin/variables.tf b/iam-cloud-admin/variables.tf
new file mode 100644
index 0000000..e27308d
--- /dev/null
+++ b/iam-cloud-admin/variables.tf
@@ -0,0 +1,20 @@
+variable "bucket_name" {
+ description = "VPC Flow Logs S3 bucket name"
+ type = string
+ # default = "inf-flowlogs-{{ tf_account }}-{{ region }}"
+ # default = "inf-flowlogs-{{ tf_account }}"
+ default = ""
+}
+
+variable "bucket_name_prefix" {
+ # description = "VPC Flow Logs S3 bucket prefix, prepended to the AWS account ID and region to make the bucket name."
+ description = "VPC Flow Logs S3 bucket prefix, prepended to the AWS account ID to make the bucket name."
+ type = string
+ default = "inf-flowlogs"
+}
+
+variable "component_tags" {
+ description = "Additional tags for Components (s3, kms, ddb)"
+ type = map(map(string))
+ default = { "s3" = {}, "kms" = {}, "ddb" = {} }
+}
diff --git a/iam-cloud-admin/version.tf b/iam-cloud-admin/version.tf
new file mode 120000
index 0000000..b83c5b7
--- /dev/null
+++ b/iam-cloud-admin/version.tf
@@ -0,0 +1 @@
+../common/version.tf
\ No newline at end of file