Skip to content

Commit 2cc1fd2

Browse files
Merge pull request #6 from Daemon-Solutions/SD-3177
SD-3177. Lambda Improvements and Documentation
2 parents 94c0395 + 291204b commit 2cc1fd2

File tree

5 files changed

+137
-26
lines changed

5 files changed

+137
-26
lines changed

README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,76 @@ Outputs
5050
-------
5151

5252
See [outputs file](outputs.tf)
53+
54+
<!-- BEGIN_TF_DOCS -->
55+
## Requirements
56+
57+
| Name | Version |
58+
|------|---------|
59+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | > 0.11 |
60+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12 |
61+
62+
## Providers
63+
64+
| Name | Version |
65+
|------|---------|
66+
| <a name="provider_archive"></a> [archive](#provider\_archive) | n/a |
67+
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |
68+
| <a name="provider_null"></a> [null](#provider\_null) | n/a |
69+
70+
## Modules
71+
72+
No modules.
73+
74+
## Resources
75+
76+
| Name | Type |
77+
|------|------|
78+
| [aws_autoscaling_notification.manage_dns_asg_notification](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/autoscaling_notification) | resource |
79+
| [aws_iam_role.lambda_manage_dns_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
80+
| [aws_iam_role_policy.lambda_manage_dns_logging_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
81+
| [aws_iam_role_policy.lambda_manage_dns_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
82+
| [aws_lambda_function.manage_dns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |
83+
| [aws_lambda_permission.manage_dns_asg_sns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
84+
| [aws_sns_topic.manage_dns_asg_sns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
85+
| [aws_sns_topic_subscription.sns_topic_subscription](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
86+
| [null_resource.notify_sns_topic](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
87+
| [archive_file.lambda_package](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
88+
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
89+
90+
## Inputs
91+
92+
| Name | Description | Type | Default | Required |
93+
|------|-------------|------|---------|:--------:|
94+
| <a name="input_asg_count"></a> [asg\_count](#input\_asg\_count) | Number of the Autoscaling Groups defined in asg\_names variable. Only here because count cannot be computed | `string` | `"1"` | no |
95+
| <a name="input_asg_names"></a> [asg\_names](#input\_asg\_names) | Name of the Autoscaling Groups to attach this Lambda Function to | `list(string)` | n/a | yes |
96+
| <a name="input_enabled"></a> [enabled](#input\_enabled) | Enable or disable the Lambda DNS functionality. | `string` | `"1"` | no |
97+
| <a name="input_environment"></a> [environment](#input\_environment) | Environment | `string` | n/a | yes |
98+
| <a name="input_lambda_function_name"></a> [lambda\_function\_name](#input\_lambda\_function\_name) | The name of the Lambda Function to create, which will manage the Autoscaling Groups | `string` | n/a | yes |
99+
| <a name="input_manage_instance_dns"></a> [manage\_instance\_dns](#input\_manage\_instance\_dns) | Whether to manage DNS records for Autoscaling Group instances | `bool` | `true` | no |
100+
| <a name="input_manage_private_asg_dns"></a> [manage\_private\_asg\_dns](#input\_manage\_private\_asg\_dns) | Whether to manage DNS records for private Autoscaling Group instances | `bool` | `false` | no |
101+
| <a name="input_manage_public_asg_dns"></a> [manage\_public\_asg\_dns](#input\_manage\_public\_asg\_dns) | Whether to manage DNS records for public Autoscaling Group instances | `bool` | `false` | no |
102+
| <a name="input_pd_escalation_policy"></a> [pd\_escalation\_policy](#input\_pd\_escalation\_policy) | PagerDuty Escalation Policy | `string` | n/a | yes |
103+
| <a name="input_pd_priority"></a> [pd\_priority](#input\_pd\_priority) | PagerDuty Priority ID | `string` | n/a | yes |
104+
| <a name="input_pd_service"></a> [pd\_service](#input\_pd\_service) | PagerDuty Service ID | `string` | n/a | yes |
105+
| <a name="input_pd_user_email"></a> [pd\_user\_email](#input\_pd\_user\_email) | PagerDuty Registered User Email | `string` | n/a | yes |
106+
| <a name="input_private_asg_record_template"></a> [private\_asg\_record\_template](#input\_private\_asg\_record\_template) | The fully qualified domain name format for private Autoscaling Group DNS records | `string` | `"service.internal.domain"` | no |
107+
| <a name="input_private_instance_record_template"></a> [private\_instance\_record\_template](#input\_private\_instance\_record\_template) | The fully qualified domain name format for private instance DNS records | `string` | `"service.az.domain"` | no |
108+
| <a name="input_public_asg_record_template"></a> [public\_asg\_record\_template](#input\_public\_asg\_record\_template) | The fully qualified domain name format for public Autoscaling Group DNS records | `string` | `"service.domain"` | no |
109+
| <a name="input_runtime"></a> [runtime](#input\_runtime) | Runtime binary | `string` | `"python3.7"` | no |
110+
| <a name="input_secret_name"></a> [secret\_name](#input\_secret\_name) | Daemon Secret Manager | `string` | n/a | yes |
111+
| <a name="input_service"></a> [service](#input\_service) | Autoscaling Group service name, e.g. 'bastion'. This will be prefix for DNS records. | `string` | n/a | yes |
112+
| <a name="input_slack_webhook"></a> [slack\_webhook](#input\_slack\_webhook) | slack webhook for notifications | `string` | n/a | yes |
113+
| <a name="input_sns_topic_name"></a> [sns\_topic\_name](#input\_sns\_topic\_name) | Name for the SNS topic which will handle notifications of instance launch and terminate events | `string` | n/a | yes |
114+
| <a name="input_ttl"></a> [ttl](#input\_ttl) | TTL value for the DNS record(s) | `number` | `60` | no |
115+
| <a name="input_zone_id"></a> [zone\_id](#input\_zone\_id) | Id of a zone file to add records to | `string` | n/a | yes |
116+
117+
## Outputs
118+
119+
| Name | Description |
120+
|------|-------------|
121+
| <a name="output_lambda_function_arn"></a> [lambda\_function\_arn](#output\_lambda\_function\_arn) | n/a |
122+
| <a name="output_lambda_function_name"></a> [lambda\_function\_name](#output\_lambda\_function\_name) | n/a |
123+
| <a name="output_lambda_manage_dns_role_arn"></a> [lambda\_manage\_dns\_role\_arn](#output\_lambda\_manage\_dns\_role\_arn) | n/a |
124+
| <a name="output_sns_topic_arn"></a> [sns\_topic\_arn](#output\_sns\_topic\_arn) | n/a |
125+
<!-- END_TF_DOCS -->

iam.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ resource "aws_iam_role_policy" "lambda_manage_dns_policy" {
5858
"ec2:DescribeInstances"
5959
],
6060
"Resource": "*"
61+
},
62+
{
63+
"Effect": "Allow",
64+
"Action": [
65+
"secretsmanager:Get*",
66+
"secretsmanager:List*"
67+
],
68+
"Resource": "*"
6169
}
6270
]
6371
}

include/lambda.py

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,23 @@
99
from string import Template
1010

1111

12+
1213
zone_id = os.environ['ZONE_ID']
1314
service = os.environ['SERVICE']
1415
ttl = int(os.environ['TTL'])
1516
webhook_url = os.environ['SLACK_WEBHOOK']
1617
environment = os.environ['ENVIRONMENT']
17-
pd_key = os.environ['PD_KEY']
18-
dedup_pd_key = os.environ['PD_DEDUP_KEY']
19-
pd_message = os.environ['PD_MESSAGE']
18+
secret_name = os.environ['SECRET_NAME']
19+
pd_service = os.environ['PD_SERVICE']
20+
pd_escalation_policy = os.environ['PD_ESCALATION_POLICY']
21+
pd_priority = os.environ['PD_PRIORITY']
22+
pd_user_email = os.environ['PD_USER_EMAIL']
23+
24+
2025
datestamp = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%f")
2126

22-
PD_DATA = ('{"payload": {"summary": "' + pd_message + '","timestamp": "' + datestamp + '","severity": "critical","source": "Laguna Rundeck PROD"},"routing_key": "' + pd_key + '", "dedup_key": "' + dedup_pd_key + '","event_action": "trigger"}')
27+
PD_DATA = ('{"incident":{"type":"incident","title": "Rundeck ' + environment + ' has restarted!","service":{"id":"' + pd_service + '","type":"service_reference"},"priority":{"id":"' + pd_priority + '","type":"priority_reference"},"urgency":"high","incident_key":"test1","body":{"type":"incident_body","details":"Rundeck ' + environment + ' has restarted!"},"escalation_policy":{"id":"' + pd_escalation_policy + '","type":"escalation_policy_reference"}}}')
28+
2329

2430
private_instance_record_template = os.environ['PRIVATE_INSTANCE_RECORD_TEMPLATE']
2531
private_asg_record_template = os.environ['PRIVATE_ASG_RECORD_TEMPLATE']
@@ -85,6 +91,18 @@ def slack_notification(message):
8591
return True
8692

8793

94+
def get_secret(secret_name):
95+
96+
session = boto3.session.Session()
97+
client = session.client(
98+
service_name='secretsmanager',
99+
region_name=aws_region
100+
)
101+
102+
get_secret_value_response = client.get_secret_value(SecretId=secret_name)
103+
104+
secret = json.loads(get_secret_value_response['SecretString'])
105+
return secret
88106

89107
def lambda_handler(event, context):
90108

@@ -200,18 +218,20 @@ def lambda_handler(event, context):
200218
slack_notification('Rundeck ' + environment + ' has restarted!!')
201219

202220
#PagerDuty Alert
203-
if environment == "production":
204-
data = json.loads(PD_DATA)
205-
data = json.dumps(data)
206-
data = data.encode()
207-
http = urllib3.PoolManager()
208-
response = http.request('POST',
209-
'https://events.pagerduty.com/v2/enqueue',
210-
body = data,
211-
headers = {'Content-Type': 'application/json'},
212-
retries = False)
213-
content = response.read()
214-
print(content)
221+
data = json.loads(PD_DATA)
222+
data = json.dumps(data)
223+
data = data.encode()
224+
http = urllib3.PoolManager()
225+
secret_value = get_secret(secret_name)
226+
new_secret_value = (secret_value['pager_duty_api_key'])
227+
print("new_secret_value " + new_secret_value)
228+
response = http.request('POST',
229+
'https://api.pagerduty.com/incidents',
230+
body = data,
231+
headers = {'Content-Type': 'application/json','Accept': 'application/vnd.pagerduty+json;version=2','Authorization': 'Token token=' + str(new_secret_value) + '', 'From': '' + pd_user_email + ''},
232+
retries = False)
233+
content = response.read()
234+
print(content)
215235

216236

217237
# helpers

main.tf

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ resource "aws_lambda_function" "manage_dns" {
2727
SERVICE = var.service
2828
SLACK_WEBHOOK = var.slack_webhook
2929
ENVIRONMENT = var.environment
30-
PD_KEY = var.pd_key
31-
PD_DEDUP_KEY = var.dedup_pd_key
32-
PD_MESSAGE = var.pd_message
30+
PD_SERVICE = var.pd_service
31+
PD_PRIORITY = var.pd_priority
32+
PD_ESCALATION_POLICY = var.pd_escalation_policy
33+
PD_USER_EMAIL = var.pd_user_email
34+
SECRET_NAME = var.secret_name
3335
PRIVATE_INSTANCE_RECORD_TEMPLATE = var.private_instance_record_template
3436
PRIVATE_ASG_RECORD_TEMPLATE = var.private_asg_record_template
3537
PUBLIC_ASG_RECORD_TEMPLATE = var.public_asg_record_template

variables.tf

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,27 @@ variable "environment" {
8585
description = "Environment"
8686
}
8787

88-
variable "pd_key" {
88+
variable "pd_service" {
8989
type = string
90-
description = "PagerDuty Token Key"
90+
description = "PagerDuty Service ID"
9191
}
9292

93-
variable "dedup_pd_key" {
93+
variable "pd_priority" {
9494
type = string
95-
description = "PagerDuty Dedup Key"
95+
description = "PagerDuty Priority ID"
9696
}
9797

98-
variable "pd_message" {
98+
variable "pd_escalation_policy" {
9999
type = string
100-
description = "PagerDuty Message"
101-
default = "Error!"
100+
description = "PagerDuty Escalation Policy"
102101
}
103102

103+
variable "pd_user_email" {
104+
type = string
105+
description = "PagerDuty Registered User Email"
106+
}
107+
108+
variable "secret_name" {
109+
type = string
110+
description = "Daemon Secret Manager"
111+
}

0 commit comments

Comments
 (0)