Skip to content

Commit 41981b7

Browse files
authored
Merge pull request #12 from SumoLogic/hsharma-elb-module
Adding variables to ELB module
2 parents 851a34b + 6bd31e6 commit 41981b7

File tree

11 files changed

+593
-0
lines changed

11 files changed

+593
-0
lines changed

aws/elasticloadbalancing/README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# SumoLogic-AWS-Elasticloadbalancing
2+
3+
This module is used to create AWS and Sumo Logic resource to collect ELB logs from an AWS S3 bucket. Features include
4+
- Create AWS S3 bucket or use an existing AWS S3 bucket.
5+
- Create AWS IAM role or use an existing IAM role.
6+
- Create AWS SNS Topic or use an existing AWS SNS topic.
7+
- Create Sumo Logic hosted collector or use an existing Sumo Logic hosted collector.
8+
- Create Sumo Logic ELB source.
9+
- Auto enable access logs for Existing and New load balancer after installing the module.
10+
11+
## Requirements
12+
13+
| Name | Version |
14+
|------|---------|
15+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.0 |
16+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.42.0 |
17+
| <a name="requirement_random"></a> [random](#requirement\_random) | >=3.1.0 |
18+
| <a name="requirement_sumologic"></a> [sumologic](#requirement\_sumologic) | >= 2.9.0 |
19+
| <a name="requirement_time"></a> [time](#requirement\_time) | >=0.7.1 |
20+
21+
## Providers
22+
23+
| Name | Version |
24+
|------|---------|
25+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.42.0 |
26+
| <a name="provider_random"></a> [random](#provider\_random) | >=3.1.0 |
27+
| <a name="provider_sumologic"></a> [sumologic](#provider\_sumologic) | >= 2.9.0 |
28+
| <a name="provider_time"></a> [time](#provider\_time) | >=0.7.1 |
29+
30+
## Modules
31+
32+
No modules.
33+
34+
## Resources
35+
36+
| Name | Type |
37+
|------|------|
38+
| [aws_iam_policy.iam_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
39+
| [aws_iam_role.source_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
40+
| [aws_s3_bucket.s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
41+
| [aws_s3_bucket_notification.bucket_notification](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_notification) | resource |
42+
| [aws_serverlessapplicationrepository_cloudformation_stack.auto_enable_access_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/serverlessapplicationrepository_cloudformation_stack) | resource |
43+
| [aws_sns_topic.sns_topic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
44+
| [aws_sns_topic_subscription.subscription](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
45+
| [random_string.aws_random](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
46+
| [sumologic_collector.collector](https://registry.terraform.io/providers/SumoLogic/sumologic/latest/docs/resources/collector) | resource |
47+
| [sumologic_elb_source.source](https://registry.terraform.io/providers/SumoLogic/sumologic/latest/docs/resources/elb_source) | resource |
48+
| [time_sleep.wait_for_seconds](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |
49+
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
50+
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
51+
| [aws_serverlessapplicationrepository_application.app](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/serverlessapplicationrepository_application) | data source |
52+
| [sumologic_caller_identity.current](https://registry.terraform.io/providers/SumoLogic/sumologic/latest/docs/data-sources/caller_identity) | data source |
53+
54+
## Inputs
55+
56+
| Name | Description | Type | Default | Required |
57+
|------|-------------|------|---------|:--------:|
58+
| <a name="input_app_semantic_version"></a> [app\_semantic\_version](#input\_app\_semantic\_version) | Provide the latest version of Serverless Application Repository 'sumologic-s3-logging-auto-enable'. | `string` | `"1.0.4"` | no |
59+
| <a name="input_auto_enable_access_logs"></a> [auto\_enable\_access\_logs](#input\_auto\_enable\_access\_logs) | New - Automatically enables access logging for newly created ELB resources to collect logs for ELB resources. This does not affect ELB resources already collecting logs.<br> Existing - Automatically enables access logging for existing ELB resources to collect logs for ELB resources.<br> Both - Automatically enables access logging for new and existing ELB resources.<br> None - Skips Automatic access Logging enable for ELB resources. | `string` | `"Both"` | no |
60+
| <a name="input_auto_enable_access_logs_options"></a> [auto\_enable\_access\_logs\_options](#input\_auto\_enable\_access\_logs\_options) | filter - provide a regex to filter the ELB for which access logs should be enabled. Empty means all resources. For eg :- 'Type': 'application'\|'type': 'application', will enable access logs for Application load balancer only.<br> remove\_on\_delete\_stack - provide true if you would like to disable access logging when you destroy the terraform resources. | <pre>object({<br> bucket_prefix = string<br> auto_enable_logging = string<br> filter = string<br> remove_on_delete_stack = bool<br> })</pre> | <pre>{<br> "auto_enable_logging": "",<br> "bucket_prefix": "",<br> "filter": "",<br> "remove_on_delete_stack": true<br>}</pre> | no |
61+
| <a name="input_collector_details"></a> [collector\_details](#input\_collector\_details) | Provide details for the Sumo Logic collector. If not provided, then defaults will be used. | <pre>object({<br> collector_name = string<br> description = string<br> fields = map(string)<br> })</pre> | <pre>{<br> "collector_name": "SumoLogic Elb Collector <Random ID>",<br> "description": "This collector is created using Sumo Logic terraform AWS ELB module to collect AWS elb logs.",<br> "fields": {}<br>}</pre> | no |
62+
| <a name="input_create_collector"></a> [create\_collector](#input\_create\_collector) | Provide "true" if you would like to create the Sumo Logic Collector. | `bool` | n/a | yes |
63+
| <a name="input_source_details"></a> [source\_details](#input\_source\_details) | Provide details for the Sumo Logic ELB source. If not provided, then defaults will be used. | <pre>object({<br> source_name = string<br> source_category = string<br> collector_id = string<br> description = string<br> bucket_details = object({<br> create_bucket = bool<br> bucket_name = string<br> path_expression = string<br> force_destroy_bucket = bool<br> })<br> paused = bool<br> scan_interval = string<br> sumo_account_id = number<br> cutoff_relative_time = string<br> fields = map(string)<br> iam_details = object({<br> create_iam_role = bool<br> iam_role_arn = string<br> })<br> sns_topic_details = object({<br> create_sns_topic = bool<br> sns_topic_arn = string<br> })<br> })</pre> | <pre>{<br> "bucket_details": {<br> "bucket_name": "elb-logs-random-id",<br> "create_bucket": true,<br> "force_destroy_bucket": true,<br> "path_expression": "*AWSLogs/<ACCOUNT-ID>/elasticloadbalancing/<REGION-NAME>/*"<br> },<br> "collector_id": "",<br> "cutoff_relative_time": "-1d",<br> "description": "This source is created using Sumo Logic terraform AWS elb module to collect AWS elb logs.",<br> "fields": {},<br> "iam_details": {<br> "create_iam_role": true,<br> "iam_role_arn": null<br> },<br> "paused": false,<br> "scan_interval": 300000,<br> "sns_topic_details": {<br> "create_sns_topic": true,<br> "sns_topic_arn": null<br> },<br> "source_category": "Labs/aws/elb",<br> "source_name": "Elb Source",<br> "sumo_account_id": 926226587429<br>}</pre> | no |
64+
| <a name="input_sumologic_organization_id"></a> [sumologic\_organization\_id](#input\_sumologic\_organization\_id) | Appears on the Account Overview page that displays information about your Sumo Logic organization. Used for IAM Role in Sumo Logic AWS Sources. | `string` | n/a | yes |
65+
| <a name="input_wait_for_seconds"></a> [wait\_for\_seconds](#input\_wait\_for\_seconds) | wait\_for\_seconds is used to delay sumo logic source creation. This helps persisting IAM role in AWS system.<br> Default value is 180 seconds.<br> If the AWS IAM role is created outside the module, the value can be decreased to 1 second. | `number` | `180` | no |
66+
67+
## Outputs
68+
69+
| Name | Description |
70+
|------|-------------|
71+
| <a name="output_aws_iam_role"></a> [aws\_iam\_role](#output\_aws\_iam\_role) | AWS IAM role with permission to allow Sumo Logic to read logs from S3 Bucket. |
72+
| <a name="output_aws_s3_bucket"></a> [aws\_s3\_bucket](#output\_aws\_s3\_bucket) | AWS S3 Bucket name created to Store the ELB logs. |
73+
| <a name="output_aws_s3_bucket_notification"></a> [aws\_s3\_bucket\_notification](#output\_aws\_s3\_bucket\_notification) | AWS S3 Bucket Notification attached to the AWS S3 Bucket |
74+
| <a name="output_aws_serverlessapplicationrepository_cloudformation_stack"></a> [aws\_serverlessapplicationrepository\_cloudformation\_stack](#output\_aws\_serverlessapplicationrepository\_cloudformation\_stack) | AWS CloudFormation stack for ELB Auto Enable access logs. |
75+
| <a name="output_aws_sns_subscription"></a> [aws\_sns\_subscription](#output\_aws\_sns\_subscription) | AWS SNS subscription to Sumo Logic AWS ELB source. |
76+
| <a name="output_aws_sns_topic"></a> [aws\_sns\_topic](#output\_aws\_sns\_topic) | AWS SNS topic attached to the AWS S3 bucket. |
77+
| <a name="output_random_string"></a> [random\_string](#output\_random\_string) | Random String value created. |
78+
| <a name="output_sumologic_collector"></a> [sumologic\_collector](#output\_sumologic\_collector) | Sumo Logic hosted collector. |
79+
| <a name="output_sumologic_source"></a> [sumologic\_source](#output\_sumologic\_source) | Sumo Logic AWS ELB source. |

aws/elasticloadbalancing/data.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
data "aws_region" "current" {}
2+
3+
data "aws_caller_identity" "current" {}
4+
5+
data "sumologic_caller_identity" "current" {}
6+
7+
data "aws_serverlessapplicationrepository_application" "app" {
8+
application_id = "arn:aws:serverlessrepo:us-east-1:956882708938:applications/sumologic-s3-logging-auto-enable"
9+
semantic_version = "1.0.2"
10+
}

aws/elasticloadbalancing/elb.tf

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# *************** Steps are as Below to create Sumo Logic ELB source *************** #
2+
# 1. Create AWS S3 Bucket. If the Bucket is created, create SNS Topic and SNS policy to attach to Bucket.
3+
# 2. Create IAM role in AWS with access to the bucket name provided.
4+
# 3. Create a Collector. If the Collector ID is provided, do not create a Collector.
5+
# 4. Create the source either in the collector created or in the collector id provided.
6+
# 5. Create SNS Subscription to be attached to the source and SNS Topic.
7+
# 6. Add SAM app for auto enable of access logs for ELBs.
8+
9+
resource "random_string" "aws_random" {
10+
length = 10
11+
special = false
12+
upper = false
13+
}
14+
15+
resource "aws_s3_bucket" "s3_bucket" {
16+
for_each = toset(var.source_details.bucket_details.create_bucket ? ["s3_bucket"] : [])
17+
18+
bucket = local.bucket_name
19+
force_destroy = var.source_details.bucket_details.force_destroy_bucket
20+
21+
policy = templatefile("${path.module}/templates/elb_bucket_policy.tmpl", {
22+
BUCKET_NAME = local.bucket_name
23+
ELB_ACCCOUNT_ID = local.region_to_elb_account_id[local.aws_region]
24+
})
25+
}
26+
27+
resource "aws_sns_topic" "sns_topic" {
28+
for_each = toset(var.source_details.sns_topic_details.create_sns_topic ? ["sns_topic"] : [])
29+
30+
name = "SumoLogic-Terraform-Elb-Module-${random_string.aws_random.id}"
31+
policy = templatefile("${path.module}/templates/sns_topic_policy.tmpl", {
32+
BUCKET_NAME = local.bucket_name,
33+
AWS_REGION = local.aws_region,
34+
SNS_TOPIC_NAME = "SumoLogic-Terraform-Elb-Module-${random_string.aws_random.id}",
35+
AWS_ACCOUNT = local.aws_account_id
36+
})
37+
}
38+
39+
resource "aws_s3_bucket_notification" "bucket_notification" {
40+
for_each = toset(var.source_details.sns_topic_details.create_sns_topic && var.source_details.bucket_details.create_bucket ? ["bucket_notification"] : [])
41+
42+
bucket = aws_s3_bucket.s3_bucket["s3_bucket"].id
43+
44+
topic {
45+
topic_arn = aws_sns_topic.sns_topic["sns_topic"].arn
46+
events = ["s3:ObjectCreated:Put"]
47+
}
48+
}
49+
50+
resource "aws_iam_role" "source_iam_role" {
51+
for_each = toset(var.source_details.iam_details.create_iam_role ? ["source_iam_role"] : [])
52+
53+
name = "SumoLogic-Terraform-Elb-Module-${random_string.aws_random.id}"
54+
path = "/"
55+
56+
assume_role_policy = templatefile("${path.module}/templates/sumologic_assume_role.tmpl", {
57+
SUMO_LOGIC_ACCOUNT_ID = var.source_details.sumo_account_id,
58+
ENVIRONMENT = data.sumologic_caller_identity.current.environment,
59+
SUMO_LOGIC_ORG_ID = var.sumologic_organization_id
60+
})
61+
62+
managed_policy_arns = [aws_iam_policy.iam_policy["iam_policy"].arn]
63+
}
64+
65+
resource "aws_iam_policy" "iam_policy" {
66+
for_each = toset(var.source_details.iam_details.create_iam_role ? ["iam_policy"] : [])
67+
68+
name = "SumoLogicElbSource-${random_string.aws_random.id}"
69+
policy = templatefile("${path.module}/templates/sumologic_source_policy.tmpl", {
70+
BUCKET_NAME = local.bucket_name
71+
})
72+
}
73+
74+
resource "sumologic_collector" "collector" {
75+
for_each = toset(var.create_collector ? ["collector"] : [])
76+
name = local.collector_name
77+
description = var.collector_details.description
78+
fields = var.collector_details.fields
79+
timezone = "UTC"
80+
}
81+
82+
resource "time_sleep" "wait_for_seconds" {
83+
create_duration = "${var.wait_for_seconds}s"
84+
}
85+
86+
resource "sumologic_elb_source" "source" {
87+
depends_on = [
88+
time_sleep.wait_for_seconds
89+
]
90+
91+
lifecycle {
92+
ignore_changes = [cutoff_timestamp, cutoff_relative_time]
93+
}
94+
category = var.source_details.source_category
95+
collector_id = var.create_collector ? sumologic_collector.collector["collector"].id : var.source_details.collector_id
96+
content_type = "AwsElbBucket"
97+
cutoff_relative_time = var.source_details.cutoff_relative_time
98+
description = var.source_details.description
99+
fields = var.source_details.fields
100+
name = var.source_details.source_name
101+
paused = var.source_details.paused
102+
scan_interval = var.source_details.scan_interval
103+
authentication {
104+
type = "AWSRoleBasedAuthentication"
105+
role_arn = var.source_details.iam_details.create_iam_role ? aws_iam_role.source_iam_role["source_iam_role"].arn : var.source_details.iam_details.iam_role_arn
106+
}
107+
108+
path {
109+
type = "S3BucketPathExpression"
110+
bucket_name = var.source_details.bucket_details.create_bucket ? aws_s3_bucket.s3_bucket["s3_bucket"].id : local.bucket_name
111+
path_expression = local.logs_path_expression
112+
}
113+
}
114+
115+
resource "aws_sns_topic_subscription" "subscription" {
116+
delivery_policy = jsonencode({
117+
"guaranteed" = false,
118+
"healthyRetryPolicy" = {
119+
"numRetries" = 40,
120+
"minDelayTarget" = 10,
121+
"maxDelayTarget" = 300,
122+
"numMinDelayRetries" = 3,
123+
"numMaxDelayRetries" = 5,
124+
"numNoDelayRetries" = 0,
125+
"backoffFunction" = "exponential"
126+
},
127+
"sicklyRetryPolicy" = null,
128+
"throttlePolicy" = null
129+
})
130+
endpoint = sumologic_elb_source.source.url
131+
endpoint_auto_confirms = true
132+
protocol = "https"
133+
topic_arn = var.source_details.sns_topic_details.create_sns_topic ? aws_sns_topic.sns_topic["sns_topic"].arn : var.source_details.sns_topic_details.sns_topic_arn
134+
}
135+
136+
# Reason to use the SAM app, is to have single source of truth for Auto Enable access logs functionality.
137+
resource "aws_serverlessapplicationrepository_cloudformation_stack" "auto_enable_access_logs" {
138+
for_each = toset(local.auto_enable_access_logs ? ["auto_enable_access_logs"] : [])
139+
140+
name = "Auto-Enable-Access-Logs-${var.auto_enable_access_logs_options.auto_enable_logging}-${random_string.aws_random.id}"
141+
application_id = "arn:aws:serverlessrepo:us-east-1:956882708938:applications/sumologic-s3-logging-auto-enable"
142+
semantic_version = var.app_semantic_version
143+
capabilities = data.aws_serverlessapplicationrepository_application.app.required_capabilities
144+
parameters = {
145+
BucketName = local.bucket_name
146+
BucketPrefix = var.auto_enable_access_logs_options.bucket_prefix
147+
AutoEnableLogging = var.auto_enable_access_logs_options.auto_enable_logging
148+
AutoEnableResourceOptions = var.auto_enable_access_logs
149+
FilterExpression = var.auto_enable_access_logs_options.filter
150+
RemoveOnDeleteStack = var.auto_enable_access_logs_options.remove_on_delete_stack
151+
}
152+
}

aws/elasticloadbalancing/locals.tf

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
locals {
2+
3+
aws_account_id = data.aws_caller_identity.current.account_id
4+
5+
aws_region = data.aws_region.current.id
6+
7+
# Get the default collector name if no collector name is provided.
8+
collector_name = var.collector_details.collector_name == "SumoLogic Elb Collector <Random ID>" ? "SumoLogic Elb Collector ${random_string.aws_random.id}" : var.collector_details.collector_name
9+
10+
# Get the default bucket name when no bucket is provided and create_bucket is true.
11+
bucket_name = var.source_details.bucket_details.create_bucket && var.source_details.bucket_details.bucket_name == "elb-logs-random-id" ? "elb-logs-${random_string.aws_random.id}" : var.source_details.bucket_details.bucket_name
12+
13+
# Auto enable should be called if input is anything other than None.
14+
auto_enable_access_logs = var.auto_enable_access_logs != "None" ? true : false
15+
16+
# If we create the bucket, then get the default PATH expression.
17+
logs_path_expression = var.source_details.bucket_details.create_bucket ? "*${var.auto_enable_access_logs_options.bucket_prefix}/AWSLogs/${local.aws_account_id}/elasticloadbalancing/${local.aws_region}/*" : var.source_details.bucket_details.path_expression
18+
19+
region_to_elb_account_id = {
20+
"us-east-1" = "127311923021",
21+
"us-east-2" = "033677994240",
22+
"us-west-1" = "027434742980",
23+
"us-west-2" = "797873946194",
24+
"af-south-1" = "098369216593",
25+
"ca-central-1" = "985666609251",
26+
"eu-central-1" = "054676820928",
27+
"eu-west-1" = "156460612806",
28+
"eu-west-2" = "652711504416",
29+
"eu-south-1" = "635631232127",
30+
"eu-west-3" = "009996457667",
31+
"eu-north-1" = "897822967062",
32+
"ap-east-1" = "754344448648",
33+
"ap-northeast-1" = "582318560864",
34+
"ap-northeast-2" = "600734575887",
35+
"ap-northeast-3" = "383597477331",
36+
"ap-southeast-1" = "114774131450",
37+
"ap-southeast-2" = "783225319266",
38+
"ap-south-1" = "718504428378",
39+
"me-south-1" = "076674570225",
40+
"sa-east-1" = "507241528517",
41+
"us-gov-west-1" = "048591011584",
42+
"us-gov-east-1" = "190560391635",
43+
"cn-north-1" = "638102146993",
44+
"cn-northwest-1" = "037604701340"
45+
}
46+
}

0 commit comments

Comments
 (0)