From 8fd89fb8b148b3961fd3819b3b9077be64df97d3 Mon Sep 17 00:00:00 2001 From: badra001 Date: Tue, 2 Mar 2021 14:01:15 -0500 Subject: [PATCH] v1.6.0: add iam-cloud-admin --- CHANGELOG.md | 3 + common/version.tf | 2 +- iam-cloud-admin/README.md | 87 +++++++++++++++ iam-cloud-admin/data.tf | 1 + iam-cloud-admin/defaults.tf | 1 + iam-cloud-admin/inf-roles.tf | 40 +++++++ iam-cloud-admin/main.tf | 110 +++++++++++++++++++ iam-cloud-admin/outputs.tf | 9 ++ iam-cloud-admin/policies.sts.tf | 21 ++++ iam-cloud-admin/policies.tf | 161 +++++++++++++++++++++++++++ iam-cloud-admin/policy_data.tf | 162 ++++++++++++++++++++++++++++ iam-cloud-admin/prefixes.tf | 1 + iam-cloud-admin/variables.common.tf | 1 + iam-cloud-admin/variables.tf | 20 ++++ iam-cloud-admin/version.tf | 1 + 15 files changed, 619 insertions(+), 1 deletion(-) create mode 100644 iam-cloud-admin/README.md create mode 120000 iam-cloud-admin/data.tf create mode 120000 iam-cloud-admin/defaults.tf create mode 100644 iam-cloud-admin/inf-roles.tf create mode 100644 iam-cloud-admin/main.tf create mode 100644 iam-cloud-admin/outputs.tf create mode 100644 iam-cloud-admin/policies.sts.tf create mode 100644 iam-cloud-admin/policies.tf create mode 100644 iam-cloud-admin/policy_data.tf create mode 120000 iam-cloud-admin/prefixes.tf create mode 120000 iam-cloud-admin/variables.common.tf create mode 100644 iam-cloud-admin/variables.tf create mode 120000 iam-cloud-admin/version.tf 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