A step function to maintain LDAP users via slack.
This project deploys a collection of lambda functions, an api gateway endpoint, and a step function implemented with the callback pattern that will automate disabling LDAP users via an interactive slack message.
- API Gateway: An API endpoint that responds asynchronously to slack events and triggers the Slack Listener lambda function
- LDAP Query: Lambda function used to perform actions against a target ldap database
- Slack Listener: Lambda function that responds to slack events via an asynchronously executed lambda function
- Slack Notifier: Lambda function that sends status updates to slack and a target step function
- Slack Bot: API Gateway endpoint and Lambda function that responds to slash commands from slack
-
Retrieve the LDAPS endpoint of your target AD deployment.
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 or the tests of this project for a reference architecture.
-
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
userAccountControlanddescription.Note: Refer to the following article to scope this permission to a single user: Delegate the Enable/Disable Accounts Permission in Active Directory
-
Populate an encrypted ssm parameter with this new user's password and use the key value as the input for
svc_user_pwd_ssm_keyvariable. -
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
Note: For each instance of this module, you will almost certainly need a new Slack app. This is because the API Gateway endpoints must be configured within the Slack app's settings, and only a single Interactivity Request URL can be specified per Slack app. Each instance of this module will have a different Interactivity Request URL.
-
Grant Scopes to the app, and capture the OAuth Token:
- Navigate to Features > OAuth & Permissions
- Under Scopes, select
command - Select "Install app" to your workspace
- Save off the "Bot User OAuth Token" and use it and the "Slack Signing Secret" in the next step
-
Configure your
terraform.tfvarswith the required inputs. -
Run
terraform init/apply -
Enable Interactivity and a Slash Command your slack integration:
- Go to https://api.slack.com
- Find your app
- Navigate to Features > Interactivity & Shortcuts > Interactivity
- Enter the output value
slack_event_listener_endpointfrom the terraform apply for the Request URL - Navigate to Features > Slash Commands
- Create a new command called
/ldap - Use the output value
slack_bot_listener_endpointfor the Request URL
-
Test the integration from slack by calling
/ldap runor manually by triggering the LDAP maintenance step function with the following payload:{"action": "query" }
- The AD Schema
- Bobbie Couhbor's awesome blogpost on using python-ldap via lambda
- Rigel Di Scala's blog post Write a serverless Slack chat bot using AWS
No requirements.
| Name | Version |
|---|---|
| aws | n/a |
| random | n/a |
| Name | Type |
|---|---|
| aws_iam_policy_document.cwe | data source |
| aws_iam_policy_document.cwe_trust | data source |
| aws_iam_policy_document.sfn | data source |
| aws_iam_policy_document.trust | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| domain_base_dn | Distinguished name of the domain | string |
n/a | yes |
| dynamodb_table_arn | ARN of the dynamodb to take actions against | string |
n/a | yes |
| dynamodb_table_name | Name of the dynamodb to take actions against | string |
n/a | yes |
| ldaps_url | LDAPS URL of the target domain | string |
n/a | yes |
| slack_api_token | API token used by the slack client. Located under the slack application Settings > Install App > Bot User OAuth Access Token | string |
n/a | yes |
| slack_channel_id | Channel that the slack notifier will post to | string |
n/a | yes |
| slack_signing_secret | The slack application's signing secret. Located under the slack application Settings > Basic Information | string |
n/a | yes |
| svc_user_dn | Distinguished name of the LDAP Maintenance service account used to manage simpleAD | string |
n/a | yes |
| svc_user_pwd_ssm_key | SSM parameter key that contains the LDAP Maintenance service account password | string |
n/a | yes |
| vpc_id | ID of the VPC hosting the target Simple AD instance | string |
n/a | yes |
| additional_cleanup_tasks | (Optional) List of step function tasks to execute in parallel once the cleanup action has been approved. | string |
"" |
no |
| 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 |
| enable_dynamodb_cleanup | Controls wether to enable the dynamodb cleanup resources. The lambda function and supporting resources will still be deployed. | bool |
true |
no |
| hands_off_accounts | (Optional) List of user names to filter out of the user search results | list(string) |
[] |
no |
| log_level | (Optional) Log level of the lambda output, one of: Debug, Info, Warning, Error, or Critical | string |
"Info" |
no |
| maintenance_schedule | Periodicity at which to trigger the ldap maintenance step function | string |
"cron(0 8 1 * ? *)" |
no |
| manual_approval_timeout | Timeout in seconds for the manual approval step. | number |
3600 |
no |
| project_name | Name of the project | string |
"ldap-maintainer" |
no |
| tags | Map of tags to assign to this module's resources | map(string) |
{} |
no |
| Name | Description |
|---|---|
| python_ldap_layer_arn | ARN of the python-ldap layer |
| slack_bot_listener_endpoint | Endpoint to use for the slack app's Slash Command Request URL |
| slack_event_listener_endpoint | Endpoint to use for the slack app's Interactivity Request URL |
