{"id":24503619,"url":"https://github.com/plus3it/terraform-aws-ldap-maintainer","last_synced_at":"2026-01-02T00:56:46.988Z","repository":{"id":37080153,"uuid":"215634022","full_name":"plus3it/terraform-aws-ldap-maintainer","owner":"plus3it","description":"A step function to maintain LDAP users via slack.","archived":false,"fork":false,"pushed_at":"2025-03-10T17:49:09.000Z","size":1008,"stargazers_count":8,"open_issues_count":2,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-10T18:47:52.316Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"HCL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/plus3it.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-16T20:02:47.000Z","updated_at":"2025-03-10T17:49:12.000Z","dependencies_parsed_at":"2023-02-11T11:30:52.443Z","dependency_job_id":"fa754b8d-66aa-42a9-9b69-eac3ab7a6b22","html_url":"https://github.com/plus3it/terraform-aws-ldap-maintainer","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plus3it%2Fterraform-aws-ldap-maintainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plus3it%2Fterraform-aws-ldap-maintainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plus3it%2Fterraform-aws-ldap-maintainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/plus3it%2Fterraform-aws-ldap-maintainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/plus3it","download_url":"https://codeload.github.com/plus3it/terraform-aws-ldap-maintainer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243703826,"owners_count":20334049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-01-21T23:17:52.446Z","updated_at":"2026-01-02T00:56:46.956Z","avatar_url":"https://github.com/plus3it.png","language":"HCL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# terraform-aws-ldap-maintainer\n\nA step function to maintain LDAP users via slack.\n\n## Overview\n\nThis project deploys a collection of lambda functions, an api gateway endpoint, and a step function implemented with the [callback pattern](https://docs.aws.amazon.com/step-functions/latest/dg/connect-to-resource.html#connect-wait-token) that will automate disabling LDAP users via an interactive slack message.\n\n## Architecture\n\n![State Machine Definition](_docs/state_machine_def_0.0.1.png)\n\n## Submodules\n\n- [API Gateway](/modules/api_gateway): An API endpoint that responds asynchronously to slack events and triggers the Slack Listener lambda function\n- [LDAP Query](/modules/ldap_query): Lambda function used to perform actions against a target ldap database\n- [Slack Listener](/modules/slack_listener): Lambda function that responds to slack events via an asynchronously executed lambda function\n- [Slack Notifier](/modules/slack_notifier): Lambda function that sends status updates to slack and a target step function\n- [Slack Bot](/modules/slack_bot): API Gateway endpoint and Lambda function that responds to slash commands from slack\n\n## Setup\n\n1. Retrieve the LDAPS endpoint of your target AD deployment.\n\n    **Note:** This can be accomplished via SimpleAD by creating an ALB that listens via TLS on port 636 and forwards requests to your SimpleAD A record. See the associated [AWS blog post](https://aws.amazon.com/blogs/security/how-to-configure-an-ldaps-endpoint-for-simple-ad/) or the tests of this project for a reference architecture.\n\n2. Within your LDAP directory create a user that will be used by the lambda function. This user will need read permissions to query LDAP, and write permissions to user objects for the properties `userAccountControl` and `description`.\n\n    **Note:** Refer to the following article to scope this permission to a single user: [Delegate the Enable/Disable Accounts Permission in Active Directory](https://thebackroomtech.com/2009/07/01/howto-delegate-the-enabledisable-accounts-permission-in-active-directory/)\n\n3. Populate an *encrypted* ssm parameter with this new user's password and use the key value as the input for `svc_user_pwd_ssm_key` variable.\n4. Register a new slack application at https://api.slack.com and capture the \"Slack Signing Secret\" from the \"Basic Information\" section of the app's Settings\n\n    **Note:** For each instance of this module, you will almost certainly need\n    a new Slack app. This is because the API Gateway endpoints must be configured\n    within the Slack app's settings, and only a single Interactivity Request URL\n    can be specified per Slack app. Each instance of this module will have a different\n    Interactivity Request URL.\n\n5. Grant Scopes to the app, and capture the OAuth Token:\n      1. Navigate to Features \u003e OAuth \u0026 Permissions\n      2. Under Scopes, select `command`\n      3. Select \"Install app\" to your workspace\n      4. Save off the \"Bot User OAuth Token\" and use it and the \"Slack Signing Secret\" in the next step\n6. Configure your `terraform.tfvars` with the required inputs.\n7. Run `terraform init/apply`\n8. Enable Interactivity and a Slash Command your slack integration:\n      1. Go to https://api.slack.com\n      2. Find your app\n      3. Navigate to Features \u003e Interactivity \u0026 Shortcuts \u003e Interactivity\n      4. Enter the output value `slack_event_listener_endpoint` from the terraform apply for the Request URL\n      5. Navigate to Features \u003e Slash Commands\n      6. Create a new command called `/ldap`\n      7. Use the output value `slack_bot_listener_endpoint` for the Request URL\n9. Test the integration from slack by calling `/ldap run` or manually by triggering the LDAP maintenance step function with the following payload: `{\"action\": \"query\" }`\n\n## References\n\n- The [AD Schema](https://docs.microsoft.com/en-us/windows/win32/adschema/active-directory-schema)\n- Bobbie Couhbor's awesome [blogpost](https://blog.kloud.com.au/2018/01/09/replacing-the-service-desk-with-bots-using-amazon-lex-and-amazon-connect-part-3/) on using python-ldap via lambda\n- Rigel Di Scala's blog post [Write a serverless Slack chat bot using AWS](https://chatbotslife.com/write-a-serverless-slack-chat-bot-using-aws-e2d2432c380e)\n\n\u003c!-- BEGIN TFDOCS --\u003e\n## Requirements\n\nNo requirements.\n\n## Providers\n\n| Name | Version |\n|------|---------|\n| \u003ca name=\"provider_aws\"\u003e\u003c/a\u003e [aws](#provider\\_aws) | n/a |\n| \u003ca name=\"provider_random\"\u003e\u003c/a\u003e [random](#provider\\_random) | n/a |\n\n## Resources\n\n| Name | Type |\n|------|------|\n| [aws_iam_policy_document.cwe](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.cwe_trust](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.sfn](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n| [aws_iam_policy_document.trust](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |\n\n## Inputs\n\n| Name | Description | Type | Default | Required |\n|------|-------------|------|---------|:--------:|\n| \u003ca name=\"input_domain_base_dn\"\u003e\u003c/a\u003e [domain\\_base\\_dn](#input\\_domain\\_base\\_dn) | Distinguished name of the domain | `string` | n/a | yes |\n| \u003ca name=\"input_dynamodb_table_arn\"\u003e\u003c/a\u003e [dynamodb\\_table\\_arn](#input\\_dynamodb\\_table\\_arn) | ARN of the dynamodb to take actions against | `string` | n/a | yes |\n| \u003ca name=\"input_dynamodb_table_name\"\u003e\u003c/a\u003e [dynamodb\\_table\\_name](#input\\_dynamodb\\_table\\_name) | Name of the dynamodb to take actions against | `string` | n/a | yes |\n| \u003ca name=\"input_ldaps_url\"\u003e\u003c/a\u003e [ldaps\\_url](#input\\_ldaps\\_url) | LDAPS URL of the target domain | `string` | n/a | yes |\n| \u003ca name=\"input_slack_api_token\"\u003e\u003c/a\u003e [slack\\_api\\_token](#input\\_slack\\_api\\_token) | API token used by the slack client. Located under the slack application Settings \u003e Install App \u003e Bot User OAuth Access Token | `string` | n/a | yes |\n| \u003ca name=\"input_slack_channel_id\"\u003e\u003c/a\u003e [slack\\_channel\\_id](#input\\_slack\\_channel\\_id) | Channel that the slack notifier will post to | `string` | n/a | yes |\n| \u003ca name=\"input_slack_signing_secret\"\u003e\u003c/a\u003e [slack\\_signing\\_secret](#input\\_slack\\_signing\\_secret) | The slack application's signing secret. Located under the slack application Settings \u003e Basic Information | `string` | n/a | yes |\n| \u003ca name=\"input_svc_user_dn\"\u003e\u003c/a\u003e [svc\\_user\\_dn](#input\\_svc\\_user\\_dn) | Distinguished name of the LDAP Maintenance service account used to manage simpleAD | `string` | n/a | yes |\n| \u003ca name=\"input_svc_user_pwd_ssm_key\"\u003e\u003c/a\u003e [svc\\_user\\_pwd\\_ssm\\_key](#input\\_svc\\_user\\_pwd\\_ssm\\_key) | SSM parameter key that contains the LDAP Maintenance service account password | `string` | n/a | yes |\n| \u003ca name=\"input_vpc_id\"\u003e\u003c/a\u003e [vpc\\_id](#input\\_vpc\\_id) | ID of the VPC hosting the target Simple AD instance | `string` | n/a | yes |\n| \u003ca name=\"input_additional_cleanup_tasks\"\u003e\u003c/a\u003e [additional\\_cleanup\\_tasks](#input\\_additional\\_cleanup\\_tasks) | (Optional) List of step function tasks to execute in parallel once the cleanup action has been approved. | `string` | `\"\"` | no |\n| \u003ca name=\"input_days_since_pwdlastset\"\u003e\u003c/a\u003e [days\\_since\\_pwdlastset](#input\\_days\\_since\\_pwdlastset) | Number of days since the pwdLastSet ldap attribute has been updated. This metric is used to disable the target ldap object. | `number` | `120` | no |\n| \u003ca name=\"input_enable_dynamodb_cleanup\"\u003e\u003c/a\u003e [enable\\_dynamodb\\_cleanup](#input\\_enable\\_dynamodb\\_cleanup) | Controls wether to enable the dynamodb cleanup resources. The lambda function and supporting resources will still be deployed. | `bool` | `true` | no |\n| \u003ca name=\"input_hands_off_accounts\"\u003e\u003c/a\u003e [hands\\_off\\_accounts](#input\\_hands\\_off\\_accounts) | (Optional) List of user names to filter out of the user search results | `list(string)` | `[]` | no |\n| \u003ca name=\"input_log_level\"\u003e\u003c/a\u003e [log\\_level](#input\\_log\\_level) | (Optional) Log level of the lambda output, one of: Debug, Info, Warning, Error, or Critical | `string` | `\"Info\"` | no |\n| \u003ca name=\"input_maintenance_schedule\"\u003e\u003c/a\u003e [maintenance\\_schedule](#input\\_maintenance\\_schedule) | Periodicity at which to trigger the ldap maintenance step function | `string` | `\"cron(0 8 1 * ? *)\"` | no |\n| \u003ca name=\"input_manual_approval_timeout\"\u003e\u003c/a\u003e [manual\\_approval\\_timeout](#input\\_manual\\_approval\\_timeout) | Timeout in seconds for the manual approval step. | `number` | `3600` | no |\n| \u003ca name=\"input_project_name\"\u003e\u003c/a\u003e [project\\_name](#input\\_project\\_name) | Name of the project | `string` | `\"ldap-maintainer\"` | no |\n| \u003ca name=\"input_tags\"\u003e\u003c/a\u003e [tags](#input\\_tags) | Map of tags to assign to this module's resources | `map(string)` | `{}` | no |\n\n## Outputs\n\n| Name | Description |\n|------|-------------|\n| \u003ca name=\"output_python_ldap_layer_arn\"\u003e\u003c/a\u003e [python\\_ldap\\_layer\\_arn](#output\\_python\\_ldap\\_layer\\_arn) | ARN of the python-ldap layer |\n| \u003ca name=\"output_slack_bot_listener_endpoint\"\u003e\u003c/a\u003e [slack\\_bot\\_listener\\_endpoint](#output\\_slack\\_bot\\_listener\\_endpoint) | Endpoint to use for the slack app's Slash Command Request URL |\n| \u003ca name=\"output_slack_event_listener_endpoint\"\u003e\u003c/a\u003e [slack\\_event\\_listener\\_endpoint](#output\\_slack\\_event\\_listener\\_endpoint) | Endpoint to use for the slack app's Interactivity Request URL |\n\n\u003c!-- END TFDOCS --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplus3it%2Fterraform-aws-ldap-maintainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplus3it%2Fterraform-aws-ldap-maintainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplus3it%2Fterraform-aws-ldap-maintainer/lists"}