diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d9d4ef..40106a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,3 +63,9 @@ * v1.8.2 -- 20210401 - iam-saml - use empty_metadata.xml in saml resource until real one is built by null_resource + +* v1.8.3 -- 20210401 + - ldap-ou-create + - new, used to setup the OU for creation of LDAP roles for SAML + + diff --git a/common/version.tf b/common/version.tf index 8e768cd..4c4f862 100644 --- a/common/version.tf +++ b/common/version.tf @@ -1,3 +1,3 @@ locals { - _module_version = "1.8.2" + _module_version = "1.8.3" } diff --git a/ldap-ou-create/README.md b/ldap-ou-create/README.md new file mode 100644 index 0000000..d3f18bd --- /dev/null +++ b/ldap-ou-create/README.md @@ -0,0 +1,76 @@ +# About ldap-ou-create + +This module will create the initial LDAP OU object in eBOCAS, provided credentials and the provider exists (it checks for this). +The [ldap-provider](https://github.e.it.census.gov/terraform/support/tree/master/providers/terraform-provider-ldap) binary is expected to be in your `$PATH`. +This has to be done before creating any roles with `aws-iam-role` and LDAP creation enabled. + +There are some quirks to the `ldap-provider` (we use [this](https://github.com/Pryz/terraform-provider-ldap) one), where if any +details change in the DN or the DN cannot be constructed due to missing data, a *tcp connection closed* message occurs. However, for this +one, there are no changes to the resource which are dynamic, so it can be done normally in just one step. + +# Usage + +```hcl +module "ou" { + source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//ldap-ou-create" + + enable_ldap_creation = true + ldap_user = "cn=myuser,ou=Application,o=U.S. Census Bureau,c=US" + ldap_password = "password1234$$" + + # optional + # account_id = "123456789012" + ldap_host = "ldap.e.tco.census.gov" + ldap_port = 389 +} +``` + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | +| [external](#provider\_external) | n/a | +| [ldap](#provider\_ldap) | n/a | +| [null](#provider\_null) | n/a | +| [template](#provider\_template) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [ldap_object.ou](https://registry.terraform.io/providers/hashicorp/ldap/latest/docs/resources/object) | resource | +| [null_resource.ou_ldif](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | +| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source | +| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.ec2_assume](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | +| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | +| [external_external.ldap_provider_bin](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source | +| [template_file.ou](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [account\_alias](#input\_account\_alias) | AWS Account Alias | `string` | `""` | no | +| [account\_id](#input\_account\_id) | AWS Account ID (default will pull from current user) | `string` | `""` | no | +| [component\_tags](#input\_component\_tags) | Additional tags for Components (role, policy) | `map(map(string))` |
{
"policy": {},
"role": {}
}
| no | +| [enable\_ldap\_creation](#input\_enable\_ldap\_creation) | Flag to enable/disable LDAP object creation for role group (for SAML only). Also requires LDAP credentials. | `bool` | `false` | no | +| [ldap\_host](#input\_ldap\_host) | LDAP Hostname (default is for eBOCAS) | `string` | `"ldap.e.tco.census.gov"` | no | +| [ldap\_password](#input\_ldap\_password) | LDAP password for ldap\_user for writing data into eDirectory or Active Directory | `string` | `""` | no | +| [ldap\_port](#input\_ldap\_port) | LDAP port (default is 389 but also using STARTTLS) | `number` | `389` | no | +| [ldap\_user](#input\_ldap\_user) | LDAP user for writing data into eDirectory or Active Directory | `string` | `""` | no | +| [override\_prefixes](#input\_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](#input\_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 + +No outputs. diff --git a/ldap-ou-create/bin/find_binary.sh b/ldap-ou-create/bin/find_binary.sh new file mode 100755 index 0000000..fe348ea --- /dev/null +++ b/ldap-ou-create/bin/find_binary.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +#set -e +eval "$(jq -r '@sh "PROGRAM=\(.program)"')" + +bin_path=$(which $PROGRAM 2> /dev/null) +status=$? + +if [ $status == 0 ] +then + if [ ! -x $bin_path ] + then + status=1 + fi +fi + +#jq -n --arg bin_path "$bin_path" --arg status "$status" '{"path":$bin_path,"status":$status | tonumber}' +jq -n --arg bin_path "$bin_path" --arg status "$status" '{"path":$bin_path,"status":$status}' diff --git a/ldap-ou-create/data.tf b/ldap-ou-create/data.tf new file mode 120000 index 0000000..995624d --- /dev/null +++ b/ldap-ou-create/data.tf @@ -0,0 +1 @@ +../common/data.tf \ No newline at end of file diff --git a/ldap-ou-create/defaults.tf b/ldap-ou-create/defaults.tf new file mode 120000 index 0000000..a5556ac --- /dev/null +++ b/ldap-ou-create/defaults.tf @@ -0,0 +1 @@ +../common/defaults.tf \ No newline at end of file diff --git a/ldap-ou-create/main.tf b/ldap-ou-create/main.tf new file mode 100644 index 0000000..fb43c29 --- /dev/null +++ b/ldap-ou-create/main.tf @@ -0,0 +1,99 @@ +/* +* # About ldap-ou-create +* +* This module will create the initial LDAP OU object in eBOCAS, provided credentials and the provider exists (it checks for this). +* The [ldap-provider](https://github.e.it.census.gov/terraform/support/tree/master/providers/terraform-provider-ldap) binary is expected to be in your `$PATH`. +* This has to be done before creating any roles with `aws-iam-role` and LDAP creation enabled. +* +* There are some quirks to the `ldap-provider` (we use [this](https://github.com/Pryz/terraform-provider-ldap) one), where if any +* details change in the DN or the DN cannot be constructed due to missing data, a *tcp connection closed* message occurs. However, for this +* one, there are no changes to the resource which are dynamic, so it can be done normally in just one step. +* +* # Usage +* +* ```hcl +* module "ou" { +* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//ldap-ou-create" +* +* enable_ldap_creation = true +* ldap_user = "cn=myuser,ou=Application,o=U.S. Census Bureau,c=US" +* ldap_password = "password1234$$" +* +* # optional +* # account_id = "123456789012" +* ldap_host = "ldap.e.tco.census.gov" +* ldap_port = 389 +* } +* ``` +*/ + +locals { + account_id = var.account_id != "" ? var.account_id : data.aws_caller_identity.current.account_id + region = data.aws_region.current.name + account_environment = data.aws_arn.current.partition == "aws-us-gov" ? "gov" : "ew" + + ldif_file = format("%v/setup/ou.%v.ldif", path.root, local.account_id) + ldap_exists = fileexists(local.ldif_file) + bocappdata_auth = local.account_environment == "gov" ? "Cloud_AWSGovCloud_Auth" : "Cloud_AWS_Auth" + + ldap_provider_exists = data.external.ldap_provider_bin.result.status == "0" ? true : false + enable_ldap = var.enable_ldap_creation && var.ldap_user != "" && var.ldap_password != "" && local.ldap_provider_exists + + base_tags = { + "boc:tf_module_version" = local._module_version + "boc:created_by" = "terraform" + } +} + +data "template_file" "ou" { + template = file("${path.module}/templates/ou-ldif.tpl") + vars = { + account_id = local.account_id + aws_environment = local.account_environment + } +} + +resource "null_resource" "ou_ldif" { + count = local.enable_ldap ? 1 : 0 + provisioner "local-exec" { + command = "test -d ${path.root}/setup || mkdir ${path.root}/setup" + } + provisioner "local-exec" { + command = "echo '${data.template_file.ou.rendered}' > ${path.root}/setup/ou.${local.account_id}.ldif" + } + provisioner "local-exec" { + command = "echo 'Once complete, execute tf-apply again to create LDAP group'" + } +} + +resource "ldap_object" "ou" { + # count = local.ldap_exists && local.enable_ldap ? 1 : 0 + count = local.enable_ldap ? 1 : 0 + provider = ldap + dn = format("ou=%s,ou=AWS,ou=Cloud,ou=Application,o=U.S. Census Bureau,c=US", local.account_id) + object_classes = [ + "top", + "organizationalUnit", + "ndsLoginProperties", + "ndsContainerLoginProperties", + ] + attributes = [ + { description = format("account=%s type=%s", local.account_id, local.account_environment) }, + { ou = local.account_id }, + ] + + lifecycle { + ignore_changes = [object_classes, attributes] + } +} + +# data.external.ldap_provider_bin.result.path +# data.external.ldap_provider_bin.result.status +data "external" "ldap_provider_bin" { + program = ["bash", "${path.module}/bin/find_binary.sh"] + query = { + "program" = "terraform-provider-ldap" + } +} + + diff --git a/ldap-ou-create/outputs.tf b/ldap-ou-create/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/ldap-ou-create/policies.tf b/ldap-ou-create/policies.tf new file mode 100644 index 0000000..726d3b6 --- /dev/null +++ b/ldap-ou-create/policies.tf @@ -0,0 +1,15 @@ +#---- +# 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"] + } + } +} diff --git a/ldap-ou-create/prefixes.tf b/ldap-ou-create/prefixes.tf new file mode 120000 index 0000000..7e265d5 --- /dev/null +++ b/ldap-ou-create/prefixes.tf @@ -0,0 +1 @@ +../common/prefixes.tf \ No newline at end of file diff --git a/ldap-ou-create/provider.ldap.tf b/ldap-ou-create/provider.ldap.tf new file mode 100644 index 0000000..a23be2b --- /dev/null +++ b/ldap-ou-create/provider.ldap.tf @@ -0,0 +1,7 @@ +provider "ldap" { + ldap_host = var.ldap_host + ldap_port = var.ldap_port + use_tls = true + bind_user = var.ldap_user + bind_password = var.ldap_password +} diff --git a/ldap-ou-create/templates/ou-ldif.tpl b/ldap-ou-create/templates/ou-ldif.tpl new file mode 100644 index 0000000..5a8e45f --- /dev/null +++ b/ldap-ou-create/templates/ou-ldif.tpl @@ -0,0 +1,10 @@ +# fields: account_id aws_environment + +# ${account_id}, AWS, Cloud, Application, U.S. Census Bureau, US +dn: ou=${account_id},ou=AWS,ou=Cloud,ou=Application,o=U.S. Census Bureau,c=US +ou: ${account_id} +description: account=${account_id} type=${aws_environment} +objectClass: organizationalUnit +objectClass: ndsLoginProperties +objectClass: ndsContainerLoginProperties +objectClass: Top diff --git a/ldap-ou-create/variables.common.tf b/ldap-ou-create/variables.common.tf new file mode 120000 index 0000000..7439ed8 --- /dev/null +++ b/ldap-ou-create/variables.common.tf @@ -0,0 +1 @@ +../common/variables.common.tf \ No newline at end of file diff --git a/ldap-ou-create/variables.tf b/ldap-ou-create/variables.tf new file mode 100644 index 0000000..4eb8f14 --- /dev/null +++ b/ldap-ou-create/variables.tf @@ -0,0 +1,38 @@ +variable "enable_ldap_creation" { + description = "Flag to enable/disable LDAP object creation for role group (for SAML only). Also requires LDAP credentials." + type = bool + default = false +} + +#--- +# ldap +#--- +variable "ldap_user" { + description = "LDAP user for writing data into eDirectory or Active Directory" + type = string + default = "" +} + +variable "ldap_password" { + description = "LDAP password for ldap_user for writing data into eDirectory or Active Directory" + type = string + default = "" +} + +variable "ldap_host" { + description = "LDAP Hostname (default is for eBOCAS)" + type = string + default = "ldap.e.tco.census.gov" +} + +variable "ldap_port" { + description = "LDAP port (default is 389 but also using STARTTLS)" + type = number + default = 389 +} + +variable "component_tags" { + description = "Additional tags for Components (role, policy)" + type = map(map(string)) + default = { "role" = {}, "policy" = {} } +} diff --git a/ldap-ou-create/version.tf b/ldap-ou-create/version.tf new file mode 120000 index 0000000..b83c5b7 --- /dev/null +++ b/ldap-ou-create/version.tf @@ -0,0 +1 @@ +../common/version.tf \ No newline at end of file