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)