diff --git a/CHANGELOG.md b/CHANGELOG.md index 0566b2a..cfff987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,3 +14,6 @@ * v1.3 -- 20210223 - module: rename access-logging to s3-access-logs - module: add s3-flow-logs + +* v1.4 -- 20210223 + - module: add iam-saml diff --git a/common/version.tf b/common/version.tf index 6459949..eadf0b6 100644 --- a/common/version.tf +++ b/common/version.tf @@ -1,3 +1,3 @@ locals { - _module_version = "1.3" + _module_version = "1.4" } diff --git a/iam-saml/README.md b/iam-saml/README.md new file mode 100644 index 0000000..40e5d9a --- /dev/null +++ b/iam-saml/README.md @@ -0,0 +1,74 @@ +# aws-inf-setup :: iam-saml + +This set up the default SAML provider with the enterprise IDP, id-provider.tco.census.gov. +The appropriate metadata and URL are selected from the environment either East/West (ew) +or GovCloud (gov). + +The resulting metadata XML is saved in `setup/metdata.xml`. + +# Usage +Here is a simple example, the one most commonly expected to be used. + +```hcl +module "saml" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//iam-saml" + + # optional + saml_provider_name = "Census_TCO_IDMS" +} +``` + +When creating a role to use SAML, you will need the SAML policy document as a reference: + +```hcl +resource "aws_iam_role" "role" { + name = "my-role-name" + description = "SAML role for my-role-name" + force_detach_policies = false + max_session_duration = 3600 + assume_role_policy = module.saml.saml_policy_document +} +``` + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| aws | n/a | +| null | 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_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | +| [aws_iam_saml_provider](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_saml_provider) | +| [aws_region](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | +| [null_resource](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| account\_alias | AWS Account Alias (required) | `string` | `""` | no | +| account\_id | AWS Account ID (default will pull from current user) | `string` | `""` | 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 | +| saml\_provider\_name | SAML Provider Name | `string` | `"Census_TCO_IDMS"` | 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 | +|------|-------------| +| saml\_assume\_policy | SAML Assume Policy document JSON | diff --git a/iam-saml/bin/get-saml-metadata.sh b/iam-saml/bin/get-saml-metadata.sh new file mode 100755 index 0000000..ccec1aa --- /dev/null +++ b/iam-saml/bin/get-saml-metadata.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +if [ -z $AWS_ENVIRONMENT ] +then + AWS_ENVIRONMENT=$1 +fi +if [ -z $AWS_ENVIRONMENT ] +then + AWS_ENVIRONMENT="east-west" +fi + +if [ -z $URL_PREFIX ] +then + URL_PREFIX="https://id-provider.tco.census.gov/nidp/saml2/metadata?PID=" +fi + +if [[ $AWS_ENVIRONMENT == "east-west" ]] || [[ $AWS_ENVIRONMENT == "ew" ]] +then + SELECT="urn:amazon:webservices" +fi +if [[ $AWS_ENVIRONMENT == "govcloud" ]] || [[ $AWS_ENVIRONMENT == "gov" ]] +then + SELECT="urn:amazon:webservices:govcloud" +fi + +if [ -z $SELECT ] +then + echo "* no URL available for AWS_ENVIRONMENT=$AWS_ENVIRONMENT" + exit 1 +fi + +URL="${URL_PREFIX}${SELECT}" +#OUTFILE="metadata.xml" +echo "# environment=$AWS_ENVIRONMENT command=curl -q -k $URL" >&2 +curl -q -k $URL +status=$? +echo $status + diff --git a/iam-saml/data.tf b/iam-saml/data.tf new file mode 120000 index 0000000..995624d --- /dev/null +++ b/iam-saml/data.tf @@ -0,0 +1 @@ +../common/data.tf \ No newline at end of file diff --git a/iam-saml/defaults.tf b/iam-saml/defaults.tf new file mode 120000 index 0000000..a5556ac --- /dev/null +++ b/iam-saml/defaults.tf @@ -0,0 +1 @@ +../common/defaults.tf \ No newline at end of file diff --git a/iam-saml/main.tf b/iam-saml/main.tf new file mode 100644 index 0000000..d36a538 --- /dev/null +++ b/iam-saml/main.tf @@ -0,0 +1,93 @@ +/* +* # aws-inf-setup :: iam-saml +* +* This set up the default SAML provider with the enterprise IDP, id-provider.tco.census.gov. +* The appropriate metadata and URL are selected from the environment either East/West (ew) +* or GovCloud (gov). +* +* The resulting metadata XML is saved in `setup/metdata.xml`. +* +* # Usage +* Here is a simple example, the one most commonly expected to be used. +* +* ```hcl +* module "saml" { +* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//iam-saml" +* +* # optional +* saml_provider_name = "Census_TCO_IDMS" +* } +* ``` +* +* When creating a role to use SAML, you will need the SAML policy document as a reference: +* +* ```hcl +* resource "aws_iam_role" "role" { +* name = "my-role-name" +* description = "SAML role for my-role-name" +* force_detach_policies = false +* max_session_duration = 3600 +* assume_role_policy = module.saml.saml_policy_document +* } +* ``` +*/ + +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" + + saml_ew_url = "https://signin.aws.amazon.com/saml" + saml_gov_url = "https://signin.amazonaws-us-gov.com/saml" + saml_url = local.account_environment == "gov" ? local.saml_gov_url : local.saml_ew_url + + base_tags = { + "boc:tf_module_version" = local._module_version + "boc:created_by" = "terraform" + } +} + +resource "null_resource" "saml_metadata" { + provisioner "local-exec" { + command = "test -d ${path.root}/setup || mkdir ${path.root}/setup" + } + + provisioner "local-exec" { + command = "bash ${path.module}/bin/get-saml-metadata.sh > ${path.root}/setup/metadata.xml" + environment = { + # AWS_ENVIRONMENT = var.aws_environment + AWS_ENVIRONMENT = local.account_environment + } + } +} + +resource "aws_iam_saml_provider" "saml" { + name = var.saml_provider_name + saml_metadata_document = file("${path.root}/setup/metadata.xml") + depends_on = [null_resource.saml_metadata] + + # when the provider supports tags, enable this section + # tags = merge( + # var.tags, + # local.base_tags, + # map("Name", local.provider_name), + # ) +} + +data "aws_iam_policy_document" "saml_assume" { + statement { + sid = "SAMLFederationCensusIdP" + effect = "Allow" + actions = ["sts:AssumeRoleWithSAML"] + + principals { + type = "Federated" + identifiers = [aws_iam_saml_provider.saml.arn] + } + + condition { + test = "StringEquals" + variable = "SAML:aud" + values = [local.saml_url] + } + } +} diff --git a/iam-saml/outputs.tf b/iam-saml/outputs.tf new file mode 100644 index 0000000..0ec4f5e --- /dev/null +++ b/iam-saml/outputs.tf @@ -0,0 +1,9 @@ +output "saml_provider" { + description = "SAML Provider ARN" + value = aws_iam_saml_provider.saml.arn +} + +output "saml_assume_policy" { + description = "SAML Assume Policy document JSON" + value = data.aws_iam_policy_document.saml_assume.json +} diff --git a/iam-saml/policy_data.tf b/iam-saml/policy_data.tf new file mode 100644 index 0000000..fa0d26f --- /dev/null +++ b/iam-saml/policy_data.tf @@ -0,0 +1,18 @@ +data "aws_iam_policy_document" "saml_assume" { + statement { + sid = "SAMLFederationCensusIdP" + effect = "Allow" + actions = ["sts:AssumeRoleWithSAML"] + + principals { + type = "Federated" + identifiers = [aws_iam_saml_provider.saml.arn] + } + + condition { + test = "StringEquals" + variable = "SAML:aud" + values = [local.saml_url] + } + } +} diff --git a/iam-saml/prefixes.tf b/iam-saml/prefixes.tf new file mode 120000 index 0000000..7e265d5 --- /dev/null +++ b/iam-saml/prefixes.tf @@ -0,0 +1 @@ +../common/prefixes.tf \ No newline at end of file diff --git a/iam-saml/variables.common.tf b/iam-saml/variables.common.tf new file mode 120000 index 0000000..7439ed8 --- /dev/null +++ b/iam-saml/variables.common.tf @@ -0,0 +1 @@ +../common/variables.common.tf \ No newline at end of file diff --git a/iam-saml/variables.tf b/iam-saml/variables.tf new file mode 100644 index 0000000..e5fc5c7 --- /dev/null +++ b/iam-saml/variables.tf @@ -0,0 +1,11 @@ +variable "saml_provider_name" { + description = "SAML Provider Name" + type = string + default = "Census_TCO_IDMS" +} + +variable "component_tags" { + description = "Additional tags for Components (s3, kms, ddb)" + type = map(map(string)) + default = { "s3" = {}, "kms" = {}, "ddb" = {} } +} diff --git a/iam-saml/version.tf b/iam-saml/version.tf new file mode 120000 index 0000000..b83c5b7 --- /dev/null +++ b/iam-saml/version.tf @@ -0,0 +1 @@ +../common/version.tf \ No newline at end of file diff --git a/s3-access-logs/main.tf b/s3-access-logs/main.tf index f8e0a47..339220c 100644 --- a/s3-access-logs/main.tf +++ b/s3-access-logs/main.tf @@ -43,7 +43,7 @@ locals { account_id = var.account_id != "" ? var.account_id : data.aws_caller_identity.current.account_id logs_region = data.aws_region.current.name - account_environment = data.aws_arn.current.partiion == "aws-us-gov" ? "gov" : "ew" + account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew" logs_alb_accounts = lookup(local._defaults["load-balancer"], local.account_environment, [local.account_id]) logs_alb_account = lookup(local._defaults["load-balancer"], local.logs_region, local.account_id) diff --git a/s3-flow-logs/main.tf b/s3-flow-logs/main.tf index ab40cff..5ef71a5 100644 --- a/s3-flow-logs/main.tf +++ b/s3-flow-logs/main.tf @@ -43,7 +43,7 @@ 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.partiion == "aws-us-gov" ? "gov" : "ew" + 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)