From a4250fd4475f2d0447e1c615b6498a4eeea8af51 Mon Sep 17 00:00:00 2001 From: badra001 Date: Thu, 1 Apr 2021 12:57:17 -0400 Subject: [PATCH] v1.8.3: create submodule ldap-ou-create --- CHANGELOG.md | 6 ++ common/version.tf | 2 +- ldap-ou-create/bin/find_binary.sh | 18 +++++ ldap-ou-create/data.tf | 1 + ldap-ou-create/defaults.tf | 1 + ldap-ou-create/main.tf | 110 +++++++++++++++++++++++++++ ldap-ou-create/outputs.tf | 10 +++ ldap-ou-create/policies.tf | 15 ++++ ldap-ou-create/prefixes.tf | 1 + ldap-ou-create/provider.ldap.tf | 7 ++ ldap-ou-create/templates/ou-ldif.tpl | 10 +++ ldap-ou-create/variables.common.tf | 1 + ldap-ou-create/variables.tf | 90 ++++++++++++++++++++++ ldap-ou-create/version.tf | 1 + 14 files changed, 272 insertions(+), 1 deletion(-) create mode 100755 ldap-ou-create/bin/find_binary.sh create mode 120000 ldap-ou-create/data.tf create mode 120000 ldap-ou-create/defaults.tf create mode 100644 ldap-ou-create/main.tf create mode 100644 ldap-ou-create/outputs.tf create mode 100644 ldap-ou-create/policies.tf create mode 120000 ldap-ou-create/prefixes.tf create mode 100644 ldap-ou-create/provider.ldap.tf create mode 100644 ldap-ou-create/templates/ou-ldif.tpl create mode 120000 ldap-ou-create/variables.common.tf create mode 100644 ldap-ou-create/variables.tf create mode 120000 ldap-ou-create/version.tf 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/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..d242b6e --- /dev/null +++ b/ldap-ou-create/main.tf @@ -0,0 +1,110 @@ +/* +* # 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. +* +* Because of this quirk, this is a two-step apply. The first step creates the IAM role and creates an LDIF file in +* `setup/{role-name}.ldif`. It uses the presence of this file to create the LDAP object in the second step. Example: +* +* 1. Step 1, creates null resource +* ```console +* % terraform apply -target=module.ou +* ``` +* +* 2. Step 2, creates ldap object +* ```console +* % terraform apply -target=module.ou +* ``` +* +* # 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 != "" && var.saml_provider_arn != "" && 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 + 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..9f9435c --- /dev/null +++ b/ldap-ou-create/outputs.tf @@ -0,0 +1,10 @@ + +output "role_arn" { + description = "Created role ARN" + value = aws_iam_role.role.arn +} + +output "role_name" { + description = "Created role name" + value = aws_iam_role.role.name +} 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..144aab7 --- /dev/null +++ b/ldap-ou-create/variables.tf @@ -0,0 +1,90 @@ +variable "role_name" { + description = "Role/application name without prefix" + type = string +} + +variable "saml_provider_arn" { + description = "ARN of SAML Provider" + type = string + default = "" +} + +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 +} + +variable "assume_policy_document" { + description = "JSON policy document for role to assume (i.e., the SAML assume document)" + type = string + default = "" +} + +variable "attached_policies" { + description = "List of IAM Policy ARNs to attach to this role" + type = list(string) + default = [] +} + +#--- +# 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" = {} } +} + + +## #--- +## # instance role +## #--- +## variable "ec2_role_name" { +## description = "EC2 instace Role/application name without prefix" +## type = string +## default = "" +## } +## +## variable "enable_instance_role" { +## description = "Flag to enable the creation of a partner EC2 instance role with specific policies and optionally a different name" +## type = bool +## default = false +## } +## +## variable "ec2_assume_policy_document" { +## description = "JSON policy document for EC2 instance role (default is sts:AssumeRole for ec2 service)" +## type = string +## default = "" +## } +## +## variable "ec2_attached_policies" { +## description = "List of IAM Policy ARNs to attach to this EC2 instance role" +## type = list(string) +## default = [] +## } +## 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