From 50a78a62b319a6a7de29972ef0fc5a1a75600ef4 Mon Sep 17 00:00:00 2001 From: badra001 Date: Tue, 2 Mar 2021 13:57:01 -0500 Subject: [PATCH] v1.5.1: redo polcies, add output, add managed_policies --- CHANGELOG.md | 5 + common/version.tf | 2 +- iam-general-policies/README.md | 73 ++++++++++++++ iam-general-policies/custom_policies.tf | 49 +++++++++ iam-general-policies/data.tf | 1 + iam-general-policies/defaults.tf | 1 + iam-general-policies/main.tf | 81 +++++++++++++++ iam-general-policies/managed_policies.tf | 26 +++++ iam-general-policies/outputs.tf | 34 +++++++ iam-general-policies/policy_data.tf | 120 +++++++++++++++++++++++ iam-general-policies/prefixes.tf | 1 + iam-general-policies/variables.common.tf | 1 + iam-general-policies/variables.tf | 20 ++++ iam-general-policies/version.tf | 1 + 14 files changed, 414 insertions(+), 1 deletion(-) create mode 100644 iam-general-policies/README.md create mode 100644 iam-general-policies/custom_policies.tf create mode 120000 iam-general-policies/data.tf create mode 120000 iam-general-policies/defaults.tf create mode 100644 iam-general-policies/main.tf create mode 100644 iam-general-policies/managed_policies.tf create mode 100644 iam-general-policies/outputs.tf create mode 100644 iam-general-policies/policy_data.tf create mode 120000 iam-general-policies/prefixes.tf create mode 120000 iam-general-policies/variables.common.tf create mode 100644 iam-general-policies/variables.tf create mode 120000 iam-general-policies/version.tf diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c2ddb1..6454e96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,3 +20,8 @@ * v1.5 -- 20210226 - module: add iam-general-policies + +* v1.5.1 -- 20210302 + - iam-general-policies + - add `managed_policies` for AWS managed policy references + - change `policies` to `custom_policies` diff --git a/common/version.tf b/common/version.tf index 6830365..34b1108 100644 --- a/common/version.tf +++ b/common/version.tf @@ -1,3 +1,3 @@ locals { - _module_version = "1.5" + _module_version = "1.5.1" } diff --git a/iam-general-policies/README.md b/iam-general-policies/README.md new file mode 100644 index 0000000..d3ccbc2 --- /dev/null +++ b/iam-general-policies/README.md @@ -0,0 +1,73 @@ +# aws-inf-setup :: iam-general-policies + +# Usage +Here is a simple example, the one most commonly expected to be used. + +```hcl +module "general" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//iam-general-policies" +} +``` + +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 "general_full" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//iam-general-policies" + + # optional + account_alias = "do2-govcloud" + + # 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_region](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | + +## 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 | +| component\_tags | Additional tags for Components (policy) | `map(map(string))` |
{
"policy": {}
}
| 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 | +|------|-------------| +| custom\_policies | Custom Policies | +| custom\_policy\_documents | Custom Policy Documents (no IAM policy) | +| managed\_policies | AWS Managed Policy name to ARN mapping | diff --git a/iam-general-policies/custom_policies.tf b/iam-general-policies/custom_policies.tf new file mode 100644 index 0000000..99f5d11 --- /dev/null +++ b/iam-general-policies/custom_policies.tf @@ -0,0 +1,49 @@ +locals { + policies = { + "manage_keys" = { + name = "manage-access-keys" + path = "/" + description = "Manage self access keys" + policy = data.aws_iam_policy_document.manage_keys.json + create_policy = true + } + "manage_credentials" = { + name = "manage-credentials" + path = "/" + description = "Manage self access keys and password" + policy = data.aws_iam_policy_document.manage_credentials.json + create_policy = true + } + "deny_billing" = { + name = "deny-billing" + path = "/" + description = "Policy to deny access to billing and cost allocation" + policy = data.aws_iam_policy_document.deny_billing.json + create_policy = true + } + "ec2_assume" = { + name = "ec2_assume" + description = "Policy document for EC2 sts:assumerole (instance role)" + policy = data.aws_iam_policy_document.ec2_assume.json + create_policy = false + } + "sts_assume" = { + name = "sts_assume" + description = "Policy document for sts:assume" + policy = data.aws_iam_policy_document.sts_assume.json + create_policy = false + } + "root_assume" = { + name = "root_assume" + description = "Policy document for sts:assume root" + policy = data.aws_iam_policy_document.root_assume.json + create_policy = false + } + "lambda_assume" = { + name = "lambda_assume" + description = "Policy document for sts:assume lambda" + policy = data.aws_iam_policy_document.lambda_assume.json + create_policy = false + } + } +} diff --git a/iam-general-policies/data.tf b/iam-general-policies/data.tf new file mode 120000 index 0000000..995624d --- /dev/null +++ b/iam-general-policies/data.tf @@ -0,0 +1 @@ +../common/data.tf \ No newline at end of file diff --git a/iam-general-policies/defaults.tf b/iam-general-policies/defaults.tf new file mode 120000 index 0000000..a5556ac --- /dev/null +++ b/iam-general-policies/defaults.tf @@ -0,0 +1 @@ +../common/defaults.tf \ No newline at end of file diff --git a/iam-general-policies/main.tf b/iam-general-policies/main.tf new file mode 100644 index 0000000..d85fac5 --- /dev/null +++ b/iam-general-policies/main.tf @@ -0,0 +1,81 @@ +/* +* # aws-inf-setup :: iam-general-policies +* +* # Usage +* Here is a simple example, the one most commonly expected to be used. +* +* ```hcl +* module "general" { +* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//iam-general-policies" +* } +* ``` +* +* 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 "general_full" { +* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//iam-general-policies" +* +* # optional +* account_alias = "do2-govcloud" +* +* # 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 + account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew" + + base_tags = { + "Organization" = "census:aditcio:csvd" + "boc:tf_module_version" = local._module_version + "boc:created_by" = "terraform" + } +} + +# "{key}" = { +# name = "manage-access-keys" +# path = "/" +# description = "Manage self access keys" +# policy = data.aws_iam_policy_document.manage_keys.json +# create_policy = true +# } + +locals { + iam_policies = { for k, v in local.custom_policies : k => v if(v["create_policy"] == true && v["policy"] != "") } + out_policies = { for k, v in local.iam_policies : k => { + "name" = v["name"] + "path" = v["path"] + "description" = v["description"] + "policy" = v["policy"] + "create_policy" = v["create_policy"] + "policy_arn" = aws_iam_polic.general[k] + } + } +} + +# see custom_policies.tf for local.custom_policies +resource "aws_iam_policy" "general" { + for_each = local.iam_policies + name = format("%vinf-%v", lookup(local._prefixes, "policy", ""), each.value["name"]) + path = lookup(each.value, "path", "/") + description = lookup(each.value, "description", "${each.key} policy") + policy = each.value["policy"] + + # tags = merge( + # var.tags, + # local.base_tags, + # lookup(var.component_tags, "policy", {}), + # map("Name",format("%vinf-%v", lookup(local._prefixes, "policy", ""), each.value["name"])) + # ) +} diff --git a/iam-general-policies/managed_policies.tf b/iam-general-policies/managed_policies.tf new file mode 100644 index 0000000..1b30b40 --- /dev/null +++ b/iam-general-policies/managed_policies.tf @@ -0,0 +1,26 @@ +locals { + managed_policies = { + "AdministratorAccess" = { + arn = format("arn:%v:iam::aws:policy/%v", data.aws_arn.current.partition, "AdministratorAccess") + } + "ReadOnlyAccess" = { + arn = format("arn:%v:iam::aws:policy/%v", data.aws_arn.current.partition, "ReadOnlyAccess") + } + "AmazonVPCFullAccess" = { + arn = format("arn:%v:iam::aws:policy/%v", data.aws_arn.current.partition, "AmazonVPCFullAccess") + } + "AWSSupportAccess" = { + arn = format("arn:%v:iam::aws:policy/%v", data.aws_arn.current.partition, "AWSSupportAccess") + } + "CloudWatchAWSSupportAccess" = { + arn = format("arn:%v:iam::aws:policy/%v", data.aws_arn.current.partition, "CloudWatchAWSSupportAccess") + } + + "Billing" = { + arn = format("arn:%v:iam::aws:policy/%v", data.aws_arn.current.partition, "job-function/Billing") + } + "NetworkAdministrator" = { + arn = format("arn:%v:iam::aws:policy/%v", data.aws_arn.current.partition, "job-function/NetworkAdministrator") + } + } +} diff --git a/iam-general-policies/outputs.tf b/iam-general-policies/outputs.tf new file mode 100644 index 0000000..851de96 --- /dev/null +++ b/iam-general-policies/outputs.tf @@ -0,0 +1,34 @@ +# name = { +# arn +# } + +output "managed_policies" { + description = "AWS Managed Policy name to ARN mapping" + values = local.managed_policies +} + +# name = { +# name +# path +# description +# policy (document) +# create_policy +# policy_arn +# } + +output "custom_policies" { + description = "Custom Policies" + values = local.out_poicies +} + +# name = { +# name +# description +# policy (document) +# create_policy +# } + +output "custom_policy_documents" { + description = "Custom Policy Documents (no IAM policy)" + values = { for k, v in local.custom_policies : k => v if(v["create_policy"] == false && v["policy"] != "") } +} diff --git a/iam-general-policies/policy_data.tf b/iam-general-policies/policy_data.tf new file mode 100644 index 0000000..a9d1285 --- /dev/null +++ b/iam-general-policies/policy_data.tf @@ -0,0 +1,120 @@ +#--- +# iam policies +#--- +data "aws_iam_policy_document" "manage_keys" { + statement { + sid = "ManageOwnAccessKeys" + effect = "Allow" + resources = [format("arn:%v:iam::%v:user/$${aws:username}", data.aws_arn.current.partition, "*")] + # resources = [format("arn:%v:iam::%v:user/$${aws:username}", data.aws_arn.current.partition, local.account_id) ] + # 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" "manage_credentials" { + statement { + sid = "ManageOwnAccessKeys" + effect = "Allow" + resources = [format("arn:%v:iam::%v:user/$${aws:username}", data.aws_arn.current.partition, "*")] + # resources = [format("arn:%v:iam::%v:user/$${aws:username}", data.aws_arn.current.partition, local.account_id) ] + # 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 = [format("arn:%v:iam::%v:user/$${aws:username}", data.aws_arn.current.partition, "*")] + # resources = [format("arn:%v:iam::%v:user/$${aws:username}", data.aws_arn.current.partition, local.account_id) ] + # resources = ["arn:${data.aws_arn.current.partition}:iam::*:user/$${aws:username}"] + actions = ["iam:ChangePassword"] + } +} + +data "aws_iam_policy_document" "deny_billing" { + statement { + sid = "DenyCensusBillingAndCostManagement" + effect = "Deny" + resources = ["*"] + + actions = [ + "aws-portal:*", + ] + } +} + + +#--- +# sts (for roles) +#--- +data "aws_iam_policy_document" "ec2_assume" { + statement { + sid = "AWSEC2AssumeRole" + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["ec2.amazonaws.com"] + } + } +} + +data "aws_iam_policy_document" "sts_assume" { + statement { + sid = "STSAssumeRole" + effect = "Allow" + actions = ["sts:AssumeRole"] + resources = ["*"] + } +} + +data "aws_iam_policy_document" "root_assume" { + statement { + sid = "STSAssumeRole" + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "AWS" + identifiers = [format("arn:%v:iam::%v:root", data.aws_arn.current.partition, local.account_id)] + # identifiers = ["arn:${data.aws_arn.current.partition}:iam::${local.account_id}:root"] + } + } +} + +#---- +# STS: lambda assume +#--- +data "aws_iam_policy_document" "lambda_assume" { + statement { + sid = "LambdaAssumeRole" + effect = "Allow" + actions = ["sts:AssumeRole"] + + principals { + type = "Service" + identifiers = ["lambda.amazonaws.com"] + } + } +} diff --git a/iam-general-policies/prefixes.tf b/iam-general-policies/prefixes.tf new file mode 120000 index 0000000..7e265d5 --- /dev/null +++ b/iam-general-policies/prefixes.tf @@ -0,0 +1 @@ +../common/prefixes.tf \ No newline at end of file diff --git a/iam-general-policies/variables.common.tf b/iam-general-policies/variables.common.tf new file mode 120000 index 0000000..7439ed8 --- /dev/null +++ b/iam-general-policies/variables.common.tf @@ -0,0 +1 @@ +../common/variables.common.tf \ No newline at end of file diff --git a/iam-general-policies/variables.tf b/iam-general-policies/variables.tf new file mode 100644 index 0000000..ba9024d --- /dev/null +++ b/iam-general-policies/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 (policy)" + type = map(map(string)) + default = { "policy" = {} } +} diff --git a/iam-general-policies/version.tf b/iam-general-policies/version.tf new file mode 120000 index 0000000..b83c5b7 --- /dev/null +++ b/iam-general-policies/version.tf @@ -0,0 +1 @@ +../common/version.tf \ No newline at end of file