Skip to content

Commit

Permalink
Merge pull request #12 from SumoLogic/hsharma-elb-module
Browse files Browse the repository at this point in the history
Adding variables to ELB module
  • Loading branch information
npande authored Feb 25, 2022
2 parents 851a34b + 6bd31e6 commit 41981b7
Show file tree
Hide file tree
Showing 11 changed files with 593 additions and 0 deletions.
79 changes: 79 additions & 0 deletions aws/elasticloadbalancing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# SumoLogic-AWS-Elasticloadbalancing

This module is used to create AWS and Sumo Logic resource to collect ELB logs from an AWS S3 bucket. Features include
- Create AWS S3 bucket or use an existing AWS S3 bucket.
- Create AWS IAM role or use an existing IAM role.
- Create AWS SNS Topic or use an existing AWS SNS topic.
- Create Sumo Logic hosted collector or use an existing Sumo Logic hosted collector.
- Create Sumo Logic ELB source.
- Auto enable access logs for Existing and New load balancer after installing the module.

## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.13.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.42.0 |
| <a name="requirement_random"></a> [random](#requirement\_random) | >=3.1.0 |
| <a name="requirement_sumologic"></a> [sumologic](#requirement\_sumologic) | >= 2.9.0 |
| <a name="requirement_time"></a> [time](#requirement\_time) | >=0.7.1 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 3.42.0 |
| <a name="provider_random"></a> [random](#provider\_random) | >=3.1.0 |
| <a name="provider_sumologic"></a> [sumologic](#provider\_sumologic) | >= 2.9.0 |
| <a name="provider_time"></a> [time](#provider\_time) | >=0.7.1 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_iam_policy.iam_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_iam_role.source_iam_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_s3_bucket.s3_bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
| [aws_s3_bucket_notification.bucket_notification](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_notification) | resource |
| [aws_serverlessapplicationrepository_cloudformation_stack.auto_enable_access_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/serverlessapplicationrepository_cloudformation_stack) | resource |
| [aws_sns_topic.sns_topic](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
| [aws_sns_topic_subscription.subscription](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
| [random_string.aws_random](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
| [sumologic_collector.collector](https://registry.terraform.io/providers/SumoLogic/sumologic/latest/docs/resources/collector) | resource |
| [sumologic_elb_source.source](https://registry.terraform.io/providers/SumoLogic/sumologic/latest/docs/resources/elb_source) | resource |
| [time_sleep.wait_for_seconds](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource |
| [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 |
| [aws_serverlessapplicationrepository_application.app](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/serverlessapplicationrepository_application) | data source |
| [sumologic_caller_identity.current](https://registry.terraform.io/providers/SumoLogic/sumologic/latest/docs/data-sources/caller_identity) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |

## Outputs

| Name | Description |
|------|-------------|
| <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. |
| <a name="output_aws_s3_bucket"></a> [aws\_s3\_bucket](#output\_aws\_s3\_bucket) | AWS S3 Bucket name created to Store the ELB logs. |
| <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 |
| <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. |
| <a name="output_aws_sns_subscription"></a> [aws\_sns\_subscription](#output\_aws\_sns\_subscription) | AWS SNS subscription to Sumo Logic AWS ELB source. |
| <a name="output_aws_sns_topic"></a> [aws\_sns\_topic](#output\_aws\_sns\_topic) | AWS SNS topic attached to the AWS S3 bucket. |
| <a name="output_random_string"></a> [random\_string](#output\_random\_string) | Random String value created. |
| <a name="output_sumologic_collector"></a> [sumologic\_collector](#output\_sumologic\_collector) | Sumo Logic hosted collector. |
| <a name="output_sumologic_source"></a> [sumologic\_source](#output\_sumologic\_source) | Sumo Logic AWS ELB source. |
10 changes: 10 additions & 0 deletions aws/elasticloadbalancing/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
data "aws_region" "current" {}

data "aws_caller_identity" "current" {}

data "sumologic_caller_identity" "current" {}

data "aws_serverlessapplicationrepository_application" "app" {
application_id = "arn:aws:serverlessrepo:us-east-1:956882708938:applications/sumologic-s3-logging-auto-enable"
semantic_version = "1.0.2"
}
152 changes: 152 additions & 0 deletions aws/elasticloadbalancing/elb.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# *************** Steps are as Below to create Sumo Logic ELB source *************** #
# 1. Create AWS S3 Bucket. If the Bucket is created, create SNS Topic and SNS policy to attach to Bucket.
# 2. Create IAM role in AWS with access to the bucket name provided.
# 3. Create a Collector. If the Collector ID is provided, do not create a Collector.
# 4. Create the source either in the collector created or in the collector id provided.
# 5. Create SNS Subscription to be attached to the source and SNS Topic.
# 6. Add SAM app for auto enable of access logs for ELBs.

resource "random_string" "aws_random" {
length = 10
special = false
upper = false
}

resource "aws_s3_bucket" "s3_bucket" {
for_each = toset(var.source_details.bucket_details.create_bucket ? ["s3_bucket"] : [])

bucket = local.bucket_name
force_destroy = var.source_details.bucket_details.force_destroy_bucket

policy = templatefile("${path.module}/templates/elb_bucket_policy.tmpl", {
BUCKET_NAME = local.bucket_name
ELB_ACCCOUNT_ID = local.region_to_elb_account_id[local.aws_region]
})
}

resource "aws_sns_topic" "sns_topic" {
for_each = toset(var.source_details.sns_topic_details.create_sns_topic ? ["sns_topic"] : [])

name = "SumoLogic-Terraform-Elb-Module-${random_string.aws_random.id}"
policy = templatefile("${path.module}/templates/sns_topic_policy.tmpl", {
BUCKET_NAME = local.bucket_name,
AWS_REGION = local.aws_region,
SNS_TOPIC_NAME = "SumoLogic-Terraform-Elb-Module-${random_string.aws_random.id}",
AWS_ACCOUNT = local.aws_account_id
})
}

resource "aws_s3_bucket_notification" "bucket_notification" {
for_each = toset(var.source_details.sns_topic_details.create_sns_topic && var.source_details.bucket_details.create_bucket ? ["bucket_notification"] : [])

bucket = aws_s3_bucket.s3_bucket["s3_bucket"].id

topic {
topic_arn = aws_sns_topic.sns_topic["sns_topic"].arn
events = ["s3:ObjectCreated:Put"]
}
}

resource "aws_iam_role" "source_iam_role" {
for_each = toset(var.source_details.iam_details.create_iam_role ? ["source_iam_role"] : [])

name = "SumoLogic-Terraform-Elb-Module-${random_string.aws_random.id}"
path = "/"

assume_role_policy = templatefile("${path.module}/templates/sumologic_assume_role.tmpl", {
SUMO_LOGIC_ACCOUNT_ID = var.source_details.sumo_account_id,
ENVIRONMENT = data.sumologic_caller_identity.current.environment,
SUMO_LOGIC_ORG_ID = var.sumologic_organization_id
})

managed_policy_arns = [aws_iam_policy.iam_policy["iam_policy"].arn]
}

resource "aws_iam_policy" "iam_policy" {
for_each = toset(var.source_details.iam_details.create_iam_role ? ["iam_policy"] : [])

name = "SumoLogicElbSource-${random_string.aws_random.id}"
policy = templatefile("${path.module}/templates/sumologic_source_policy.tmpl", {
BUCKET_NAME = local.bucket_name
})
}

resource "sumologic_collector" "collector" {
for_each = toset(var.create_collector ? ["collector"] : [])
name = local.collector_name
description = var.collector_details.description
fields = var.collector_details.fields
timezone = "UTC"
}

resource "time_sleep" "wait_for_seconds" {
create_duration = "${var.wait_for_seconds}s"
}

resource "sumologic_elb_source" "source" {
depends_on = [
time_sleep.wait_for_seconds
]

lifecycle {
ignore_changes = [cutoff_timestamp, cutoff_relative_time]
}
category = var.source_details.source_category
collector_id = var.create_collector ? sumologic_collector.collector["collector"].id : var.source_details.collector_id
content_type = "AwsElbBucket"
cutoff_relative_time = var.source_details.cutoff_relative_time
description = var.source_details.description
fields = var.source_details.fields
name = var.source_details.source_name
paused = var.source_details.paused
scan_interval = var.source_details.scan_interval
authentication {
type = "AWSRoleBasedAuthentication"
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
}

path {
type = "S3BucketPathExpression"
bucket_name = var.source_details.bucket_details.create_bucket ? aws_s3_bucket.s3_bucket["s3_bucket"].id : local.bucket_name
path_expression = local.logs_path_expression
}
}

resource "aws_sns_topic_subscription" "subscription" {
delivery_policy = jsonencode({
"guaranteed" = false,
"healthyRetryPolicy" = {
"numRetries" = 40,
"minDelayTarget" = 10,
"maxDelayTarget" = 300,
"numMinDelayRetries" = 3,
"numMaxDelayRetries" = 5,
"numNoDelayRetries" = 0,
"backoffFunction" = "exponential"
},
"sicklyRetryPolicy" = null,
"throttlePolicy" = null
})
endpoint = sumologic_elb_source.source.url
endpoint_auto_confirms = true
protocol = "https"
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
}

# Reason to use the SAM app, is to have single source of truth for Auto Enable access logs functionality.
resource "aws_serverlessapplicationrepository_cloudformation_stack" "auto_enable_access_logs" {
for_each = toset(local.auto_enable_access_logs ? ["auto_enable_access_logs"] : [])

name = "Auto-Enable-Access-Logs-${var.auto_enable_access_logs_options.auto_enable_logging}-${random_string.aws_random.id}"
application_id = "arn:aws:serverlessrepo:us-east-1:956882708938:applications/sumologic-s3-logging-auto-enable"
semantic_version = var.app_semantic_version
capabilities = data.aws_serverlessapplicationrepository_application.app.required_capabilities
parameters = {
BucketName = local.bucket_name
BucketPrefix = var.auto_enable_access_logs_options.bucket_prefix
AutoEnableLogging = var.auto_enable_access_logs_options.auto_enable_logging
AutoEnableResourceOptions = var.auto_enable_access_logs
FilterExpression = var.auto_enable_access_logs_options.filter
RemoveOnDeleteStack = var.auto_enable_access_logs_options.remove_on_delete_stack
}
}
46 changes: 46 additions & 0 deletions aws/elasticloadbalancing/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
locals {

aws_account_id = data.aws_caller_identity.current.account_id

aws_region = data.aws_region.current.id

# Get the default collector name if no collector name is provided.
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

# Get the default bucket name when no bucket is provided and create_bucket is true.
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

# Auto enable should be called if input is anything other than None.
auto_enable_access_logs = var.auto_enable_access_logs != "None" ? true : false

# If we create the bucket, then get the default PATH expression.
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

region_to_elb_account_id = {
"us-east-1" = "127311923021",
"us-east-2" = "033677994240",
"us-west-1" = "027434742980",
"us-west-2" = "797873946194",
"af-south-1" = "098369216593",
"ca-central-1" = "985666609251",
"eu-central-1" = "054676820928",
"eu-west-1" = "156460612806",
"eu-west-2" = "652711504416",
"eu-south-1" = "635631232127",
"eu-west-3" = "009996457667",
"eu-north-1" = "897822967062",
"ap-east-1" = "754344448648",
"ap-northeast-1" = "582318560864",
"ap-northeast-2" = "600734575887",
"ap-northeast-3" = "383597477331",
"ap-southeast-1" = "114774131450",
"ap-southeast-2" = "783225319266",
"ap-south-1" = "718504428378",
"me-south-1" = "076674570225",
"sa-east-1" = "507241528517",
"us-gov-west-1" = "048591011584",
"us-gov-east-1" = "190560391635",
"cn-north-1" = "638102146993",
"cn-northwest-1" = "037604701340"
}
}
Loading

0 comments on commit 41981b7

Please sign in to comment.