diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7a317a..85e5bb3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -72,4 +72,8 @@
- ses-domain
- use data resource to get alias
+* v1.9.0 -- 20210405
+ - ldap-get-attribute
+ - add new submodule to retrieve an attribute value from a search
+
diff --git a/common/version.tf b/common/version.tf
index 2fd882b..e761cc8 100644
--- a/common/version.tf
+++ b/common/version.tf
@@ -1,3 +1,3 @@
locals {
- _module_version = "1.8.4"
+ _module_version = "1.9.0"
}
diff --git a/ldap-get-attribute/README.md b/ldap-get-attribute/README.md
new file mode 100644
index 0000000..462b700
--- /dev/null
+++ b/ldap-get-attribute/README.md
@@ -0,0 +1,90 @@
+# aws-inf-setup :: ldap-get-attribute
+
+This allows for a simple LDAP search filter against, by default eDirectory ldap.tco.census.gov.
+It returns an object with count, status, the attribute, the dn(s) and the attribute value(s).
+DN and values are returned in a list. This is intended to search for only a single attribute,
+which may be multi-value. It also returns the DN and CN.
+
+For a query that returns multiple entries, where those entries do all not possess the same
+attribute, the DN to attibute value will not match. That is, it returns only a list of
+the attributes for the objects which have them in no particular order.
+
+# Usage
+Here is a simple example to get the email address of use `badra001`.
+
+```hcl
+module "user_badra001" {
+ source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//ldap-get-attribute"
+
+ filter = "cn=badra001"
+ attribute = "mail"
+ # optional
+ # ldap_uri = "ldaps://ldap.tco.census.gov"
+ # ldap_base_dn = "o=U.S. Census Bureau,c=US"
+
+ # TBD
+ # ldap_user =
+ # ldap_pass =
+}
+```
+
+# Sample Output
+```json
+search_results = {
+ "attribute" = "mail"
+ "attribute_value" = [
+ "donald.e.badrak.ii@census.gov",
+ ]
+ "count" = "1"
+ "dn" = [
+ "cn=badra001,ou=People,o=U.S. Census Bureau,c=US",
+ ]
+ "cn" = [
+ "badra001"
+ ]
+ "status" = "0"
+}
+```
+
+## Requirements
+
+No requirements.
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | n/a |
+| [external](#provider\_external) | n/a |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [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_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
+| [external_external.search](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | 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 |
+| [attribute](#input\_attribute) | LDAP attibute to return | `string` | `"dn"` | no |
+| [filter](#input\_filter) | LDAP search filter | `string` | n/a | yes |
+| [ldap\_base\_dn](#input\_ldap\_base\_dn) | LDAP base DN for search | `string` | `"o=U.S. Census Bureau,c=US"` | no |
+| [ldap\_uri](#input\_ldap\_uri) | LDAP URI {scheme}://{hostname}:{port} | `string` | `"ldaps://ldap.tco.census.gov"` | 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
+
+| Name | Description |
+|------|-------------|
+| [search\_result](#output\_search\_result) | n/a |
diff --git a/ldap-get-attribute/bin/external_ldapsearch.sh b/ldap-get-attribute/bin/external_ldapsearch.sh
new file mode 100755
index 0000000..e8dbc15
--- /dev/null
+++ b/ldap-get-attribute/bin/external_ldapsearch.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+
+cleanup()
+{
+ local rstatus=$?
+ if [ ! -z $LDIF]
+ then
+ test -e $LDIF && rm $LDIF
+ fi
+ exit $rstatus
+}
+
+trap cleanup EXIT
+
+#set -e
+eval "$(jq -r '@sh "LDAP_BASE_DN=\(.ldap_base_dn) FILTER=\(.filter) ATTRIBUTE=\(.attribute) LDAP_URL=\(.ldap_url)"')"
+
+if [[ -z $LDAP_BASE_DN ]] || [[ "$LDAP_BASE_DN" == "null" ]]
+then
+ LDAP_BASE_DN="o=U.S. Census Bureau,c=US"
+fi
+
+if [[ -z $LDAP_URL ]] || [[ "$LDAP_URL" == "null" ]]
+then
+ LDAP_URL="ldaps://ldap.tco.census.gov"
+fi
+
+if [[ -z "$FILTER" ]] || [[ "$FILTER" == "null" ]]
+then
+ FILTER=""
+fi
+
+if [[ -z "$ATTRIBUTE" ]] || [[ "$ATTRIBUTE" == "null" ]]
+then
+ ATTRIBUTE="dn"
+fi
+
+if [ -z "$FILTER" ]
+then
+ echo "* no filter provided"
+ exit 1
+fi
+
+LDIF=$(mktemp)
+ldapsearch -x -LLL -o ldif-wrap=no -H "$LDAP_URL" -b "$LDAP_BASE_DN" "$FILTER" "cn $ATTRIBUTE" > $LDIF
+status=$?
+
+DN=$(grep "^dn:" $LDIF | sed -e 's/^dn: //')
+CN=$(grep "^cn:" $LDIF | sed -e 's/^cn: //')
+VALUE=$(grep -i "^$ATTRIBUTE:" $LDIF | sed -e "s/^$ATTRIBUTE: //")
+COUNT=$(grep -c "^dn:" $LDIF)
+
+jq -n --arg dn "$DN" --arg cn "$CN" --arg attribute "$ATTRIBUTE" --arg value "$VALUE" --arg status "$status" --arg count "$COUNT" \
+ '{"dn":$dn,"attribute":$attribute,"attribute_value":$value,"status":$status,"count":$count}'
diff --git a/ldap-get-attribute/data.tf b/ldap-get-attribute/data.tf
new file mode 120000
index 0000000..995624d
--- /dev/null
+++ b/ldap-get-attribute/data.tf
@@ -0,0 +1 @@
+../common/data.tf
\ No newline at end of file
diff --git a/ldap-get-attribute/defaults.tf b/ldap-get-attribute/defaults.tf
new file mode 120000
index 0000000..a5556ac
--- /dev/null
+++ b/ldap-get-attribute/defaults.tf
@@ -0,0 +1 @@
+../common/defaults.tf
\ No newline at end of file
diff --git a/ldap-get-attribute/main.tf b/ldap-get-attribute/main.tf
new file mode 100644
index 0000000..745bbb3
--- /dev/null
+++ b/ldap-get-attribute/main.tf
@@ -0,0 +1,81 @@
+/*
+* # aws-inf-setup :: ldap-get-attribute
+*
+* This allows for a simple LDAP search filter against, by default eDirectory ldap.tco.census.gov.
+* It returns an object with count, status, the attribute, the dn(s) and the attribute value(s).
+* DN and values are returned in a list. This is intended to search for only a single attribute,
+* which may be multi-value. It also returns the DN and CN.
+*
+* For a query that returns multiple entries, where those entries do all not possess the same
+* attribute, the DN to attibute value will not match. That is, it returns only a list of
+* the attributes for the objects which have them in no particular order.
+*
+* # Usage
+* Here is a simple example to get the email address of use `badra001`.
+*
+* ```hcl
+* module "user_badra001" {
+* source = "git@github.e.it.census.gov:terraform-modules/aws-inf-setup.git//ldap-get-attribute"
+*
+* filter = "cn=badra001"
+* attribute = "mail"
+* # optional
+* # ldap_uri = "ldaps://ldap.tco.census.gov"
+* # ldap_base_dn = "o=U.S. Census Bureau,c=US"
+*
+* # TBD
+* # ldap_user =
+* # ldap_pass =
+* }
+* ```
+*
+* # Sample Output
+* ```json
+* search_results = {
+* "attribute" = "mail"
+* "attribute_value" = [
+* "donald.e.badrak.ii@census.gov",
+* ]
+* "count" = "1"
+* "dn" = [
+* "cn=badra001,ou=People,o=U.S. Census Bureau,c=US",
+* ]
+* "cn" = [
+* "badra001"
+* ]
+* "status" = "0"
+* }
+* ```
+*/
+
+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"
+
+ base_tags = {
+ "boc:tf_module_version" = local._module_version
+ "boc:created_by" = "terraform"
+ }
+}
+
+data "external" "search" {
+ program = ["bash", "${path.module}/bin/external_ldapsearch.sh"]
+ # output {object}.result.{status,count,dn,attribute,attribute_value}
+ query = {
+ "ldap_uri" = var.ldap_uri
+ "ldap_base_dn" = var.ldap_base_dn
+ "filter" = var.filter
+ "attribute" = var.attribute
+ }
+}
+
+output "search_result" {
+ value = {
+ "count" = data.external.ldap_user.result.count
+ "status" = data.external.ldap_user.result.status
+ "attribute" = data.external.ldap_user.result.attribute
+ "cn" = split("\n", data.external.ldap_user.result.cn)
+ "dn" = split("\n", data.external.ldap_user.result.dn)
+ "attribute_value" = split("\n", data.external.ldap_user.result.attribute_value)
+ }
+}
diff --git a/ldap-get-attribute/prefixes.tf b/ldap-get-attribute/prefixes.tf
new file mode 120000
index 0000000..7e265d5
--- /dev/null
+++ b/ldap-get-attribute/prefixes.tf
@@ -0,0 +1 @@
+../common/prefixes.tf
\ No newline at end of file
diff --git a/ldap-get-attribute/variables.common.tf b/ldap-get-attribute/variables.common.tf
new file mode 120000
index 0000000..7439ed8
--- /dev/null
+++ b/ldap-get-attribute/variables.common.tf
@@ -0,0 +1 @@
+../common/variables.common.tf
\ No newline at end of file
diff --git a/ldap-get-attribute/variables.tf b/ldap-get-attribute/variables.tf
new file mode 100644
index 0000000..0525f38
--- /dev/null
+++ b/ldap-get-attribute/variables.tf
@@ -0,0 +1,34 @@
+variable "filter" {
+ description = "LDAP search filter"
+ type = string
+}
+
+variable "attribute" {
+ description = "LDAP attibute to return"
+ type = string
+ default = "dn"
+}
+
+variable "ldap_uri" {
+ description = "LDAP URI {scheme}://{hostname}:{port}"
+ type = string
+ default = "ldaps://ldap.tco.census.gov"
+}
+
+variable "ldap_base_dn" {
+ description = "LDAP base DN for search"
+ type = string
+ default = "o=U.S. Census Bureau,c=US"
+}
+
+# variable "ldap_user" {
+# description = "LDAP bind username"
+# type = string
+# default = ""
+# }
+#
+# variable "ldap_password" {
+# description = "LDAP bind password"
+# type = string
+# default = ""
+# }
diff --git a/ldap-get-attribute/version.tf b/ldap-get-attribute/version.tf
new file mode 120000
index 0000000..b83c5b7
--- /dev/null
+++ b/ldap-get-attribute/version.tf
@@ -0,0 +1 @@
+../common/version.tf
\ No newline at end of file