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