|
| 1 | +<!-- BEGIN_TF_DOCS --> |
| 2 | +---- |
| 3 | +## main.tf |
| 4 | +```hcl |
| 5 | +terraform { |
| 6 | + required_version = ">= 0.14.0" |
| 7 | +
|
| 8 | + required_providers { |
| 9 | + aws = { |
| 10 | + source = "hashicorp/aws" |
| 11 | + version = "4.9.0" |
| 12 | + } |
| 13 | +
|
| 14 | + random = { |
| 15 | + source = "hashicorp/random" |
| 16 | + version = "3.4.3" |
| 17 | + } |
| 18 | + } |
| 19 | +} |
| 20 | +
|
| 21 | +provider "aws" { |
| 22 | + region = "eu-west-1" |
| 23 | +} |
| 24 | +
|
| 25 | +locals { |
| 26 | + tags = { |
| 27 | + usage = "clickops-testing" |
| 28 | + run = random_pet.run_id.id |
| 29 | + } |
| 30 | +
|
| 31 | + naming_prefix = "clickops-test-basic-${random_pet.run_id.id}" |
| 32 | +} |
| 33 | +
|
| 34 | +resource "random_pet" "run_id" { |
| 35 | + keepers = { |
| 36 | + # Generate a new pet name |
| 37 | + run_id = var.run_id |
| 38 | + } |
| 39 | +} |
| 40 | +
|
| 41 | +#--------------------------------------- |
| 42 | +# Cloudtrail infrastructure - standalone |
| 43 | +#--------------------------------------- |
| 44 | +# S3 bucket |
| 45 | +module "logs_bucket" { |
| 46 | + source = "trussworks/logs/aws" |
| 47 | + version = "~> 14" |
| 48 | +
|
| 49 | + s3_bucket_name = local.naming_prefix |
| 50 | +
|
| 51 | + allow_cloudtrail = true |
| 52 | + force_destroy = true |
| 53 | +} |
| 54 | +
|
| 55 | +# Cloudtrail |
| 56 | +locals { |
| 57 | + naming_prefix_cloudtrail = "${local.naming_prefix}-cloudtrail" |
| 58 | + naming_prefix_firehose = "${local.naming_prefix}-firehose" |
| 59 | +} |
| 60 | +module "aws_cloudtrail" { |
| 61 | + source = "trussworks/cloudtrail/aws" |
| 62 | + version = "~> 4" |
| 63 | +
|
| 64 | + s3_bucket_name = module.logs_bucket.aws_logs_bucket |
| 65 | +
|
| 66 | + trail_name = local.naming_prefix_cloudtrail |
| 67 | + iam_policy_name = local.naming_prefix_cloudtrail |
| 68 | + iam_role_name = local.naming_prefix_cloudtrail |
| 69 | +
|
| 70 | + cloudwatch_log_group_name = local.naming_prefix_cloudtrail |
| 71 | + log_retention_days = 30 |
| 72 | +} |
| 73 | +
|
| 74 | +#--------------------------------------- |
| 75 | +# ClickOps module |
| 76 | +#--------------------------------------- |
| 77 | +module "clickops_notifications" { |
| 78 | + source = "../.." |
| 79 | +
|
| 80 | + standalone = true |
| 81 | +
|
| 82 | + naming_prefix = local.naming_prefix |
| 83 | +
|
| 84 | + webhook = "https://fake.com" |
| 85 | + message_format = "slack" |
| 86 | +
|
| 87 | + tags = local.tags |
| 88 | +
|
| 89 | + # cloudtrail_bucket_name = aws_s3_bucket.clickops_cloudtrail.id |
| 90 | + cloudtrail_log_group = local.naming_prefix_cloudtrail |
| 91 | +
|
| 92 | + firehose_delivery_stream_name = aws_kinesis_firehose_delivery_stream.extended_s3_stream.name |
| 93 | +
|
| 94 | + depends_on = [ |
| 95 | + module.aws_cloudtrail |
| 96 | + ] |
| 97 | +
|
| 98 | +} |
| 99 | +
|
| 100 | +#--------------------------------------- |
| 101 | +# Delivery stream infrastructure |
| 102 | +#--------------------------------------- |
| 103 | +resource "aws_kinesis_firehose_delivery_stream" "extended_s3_stream" { |
| 104 | + name = local.naming_prefix |
| 105 | + destination = "extended_s3" |
| 106 | +
|
| 107 | + extended_s3_configuration { |
| 108 | + role_arn = aws_iam_role.firehose.arn |
| 109 | + bucket_arn = aws_s3_bucket.firehose.arn |
| 110 | +
|
| 111 | + compression_format = "UNCOMPRESSED" |
| 112 | +
|
| 113 | + buffer_size = 64 |
| 114 | + buffer_interval = 300 |
| 115 | +
|
| 116 | + # Hive-style dynamic partitioning by recipientAccountId and awsRegion |
| 117 | + # https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning.html |
| 118 | +
|
| 119 | + dynamic_partitioning_configuration { |
| 120 | + enabled = "true" |
| 121 | + } |
| 122 | +
|
| 123 | + prefix = join("/", [ |
| 124 | + "data", |
| 125 | + "recipientAccountId=!{partitionKeyFromQuery:recipientAccountId}", |
| 126 | + "awsRegion=!{partitionKeyFromQuery:awsRegion}", |
| 127 | + "year=!{timestamp:yyyy}", "month=!{timestamp:MM}", "day=!{timestamp:dd}", "hour=!{timestamp:HH}", |
| 128 | + "" |
| 129 | + ]) |
| 130 | + error_output_prefix = join("/", [ |
| 131 | + "errors", |
| 132 | + "year=!{timestamp:yyyy}", "month=!{timestamp:MM}", "day=!{timestamp:dd}", "hour=!{timestamp:HH}", |
| 133 | + "!{firehose:error-output-type}", |
| 134 | + "" |
| 135 | + ]) |
| 136 | +
|
| 137 | + processing_configuration { |
| 138 | + enabled = "true" |
| 139 | +
|
| 140 | + # DeAggreagate records |
| 141 | + processors { |
| 142 | + type = "RecordDeAggregation" |
| 143 | + parameters { |
| 144 | + parameter_name = "SubRecordType" |
| 145 | + parameter_value = "JSON" |
| 146 | + } |
| 147 | + } |
| 148 | +
|
| 149 | + # Calculate partition variables |
| 150 | + processors { |
| 151 | + type = "MetadataExtraction" |
| 152 | + parameters { |
| 153 | + parameter_name = "JsonParsingEngine" |
| 154 | + parameter_value = "JQ-1.6" |
| 155 | + } |
| 156 | + parameters { |
| 157 | + parameter_name = "MetadataExtractionQuery" |
| 158 | + parameter_value = "{recipientAccountId:.recipientAccountId, awsRegion:.awsRegion}" |
| 159 | + } |
| 160 | + } |
| 161 | +
|
| 162 | + # Append new line between output records |
| 163 | + processors { |
| 164 | + type = "AppendDelimiterToRecord" |
| 165 | + } |
| 166 | + } |
| 167 | + } |
| 168 | +} |
| 169 | +
|
| 170 | +resource "aws_s3_bucket" "firehose" { |
| 171 | + bucket = local.naming_prefix_firehose |
| 172 | +} |
| 173 | +
|
| 174 | +resource "aws_s3_bucket_acl" "firehose_bucket_acl" { |
| 175 | + bucket = aws_s3_bucket.firehose.id |
| 176 | + acl = "private" |
| 177 | +} |
| 178 | +
|
| 179 | +resource "aws_iam_role" "firehose" { |
| 180 | + name = local.naming_prefix_firehose |
| 181 | +
|
| 182 | + assume_role_policy = jsonencode({ |
| 183 | + Version = "2012-10-17" |
| 184 | + Statement = [ |
| 185 | + { |
| 186 | + Action = "sts:AssumeRole" |
| 187 | + Effect = "Allow" |
| 188 | + Sid = "" |
| 189 | + Principal = { |
| 190 | + Service = "firehose.amazonaws.com" |
| 191 | + } |
| 192 | + } |
| 193 | + ] |
| 194 | + }) |
| 195 | +} |
| 196 | +
|
| 197 | +resource "aws_iam_role_policy" "firehose" { |
| 198 | + name = local.naming_prefix_firehose |
| 199 | + role = aws_iam_role.firehose.id |
| 200 | + policy = data.aws_iam_policy_document.firehose.json |
| 201 | +} |
| 202 | +
|
| 203 | +data "aws_iam_policy_document" "firehose" { |
| 204 | + statement { |
| 205 | + actions = [ |
| 206 | + "s3:AbortMultipartUpload", |
| 207 | + "s3:GetBucketLocation", |
| 208 | + "s3:GetObject", |
| 209 | + "s3:ListBucket", |
| 210 | + "s3:ListBucketMultipartUploads", |
| 211 | + "s3:PutObject" |
| 212 | + ] |
| 213 | +
|
| 214 | + resources = [ |
| 215 | + aws_s3_bucket.firehose.arn, |
| 216 | + "${aws_s3_bucket.firehose.arn}/*" |
| 217 | + ] |
| 218 | + } |
| 219 | +} |
| 220 | +``` |
| 221 | +---- |
| 222 | + |
| 223 | +## Documentation |
| 224 | + |
| 225 | +---- |
| 226 | +### Inputs |
| 227 | + |
| 228 | +| Name | Description | Type | Default | Required | |
| 229 | +|------|-------------|------|---------|:--------:| |
| 230 | +| <a name="input_run_id"></a> [run\_id](#input\_run\_id) | Used to ensure resources are unique | `string` | n/a | yes | |
| 231 | + |
| 232 | +---- |
| 233 | +### Modules |
| 234 | + |
| 235 | +| Name | Source | Version | |
| 236 | +|------|--------|---------| |
| 237 | +| <a name="module_aws_cloudtrail"></a> [aws\_cloudtrail](#module\_aws\_cloudtrail) | trussworks/cloudtrail/aws | ~> 4 | |
| 238 | +| <a name="module_clickops_notifications"></a> [clickops\_notifications](#module\_clickops\_notifications) | ../.. | n/a | |
| 239 | +| <a name="module_logs_bucket"></a> [logs\_bucket](#module\_logs\_bucket) | trussworks/logs/aws | ~> 14 | |
| 240 | + |
| 241 | +---- |
| 242 | +### Outputs |
| 243 | + |
| 244 | +No outputs. |
| 245 | + |
| 246 | +---- |
| 247 | +### Providers |
| 248 | + |
| 249 | +| Name | Version | |
| 250 | +|------|---------| |
| 251 | +| <a name="provider_aws"></a> [aws](#provider\_aws) | 4.9.0 | |
| 252 | +| <a name="provider_random"></a> [random](#provider\_random) | 3.4.3 | |
| 253 | + |
| 254 | +---- |
| 255 | +### Requirements |
| 256 | + |
| 257 | +| Name | Version | |
| 258 | +|------|---------| |
| 259 | +| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.14.0 | |
| 260 | +| <a name="requirement_aws"></a> [aws](#requirement\_aws) | 4.9.0 | |
| 261 | +| <a name="requirement_random"></a> [random](#requirement\_random) | 3.4.3 | |
| 262 | + |
| 263 | +---- |
| 264 | +### Resources |
| 265 | + |
| 266 | +| Name | Type | |
| 267 | +|------|------| |
| 268 | +| [aws_iam_role.firehose](https://registry.terraform.io/providers/hashicorp/aws/4.9.0/docs/resources/iam_role) | resource | |
| 269 | +| [aws_iam_role_policy.firehose](https://registry.terraform.io/providers/hashicorp/aws/4.9.0/docs/resources/iam_role_policy) | resource | |
| 270 | +| [aws_kinesis_firehose_delivery_stream.extended_s3_stream](https://registry.terraform.io/providers/hashicorp/aws/4.9.0/docs/resources/kinesis_firehose_delivery_stream) | resource | |
| 271 | +| [aws_s3_bucket.firehose](https://registry.terraform.io/providers/hashicorp/aws/4.9.0/docs/resources/s3_bucket) | resource | |
| 272 | +| [aws_s3_bucket_acl.firehose_bucket_acl](https://registry.terraform.io/providers/hashicorp/aws/4.9.0/docs/resources/s3_bucket_acl) | resource | |
| 273 | +| [random_pet.run_id](https://registry.terraform.io/providers/hashicorp/random/3.4.3/docs/resources/pet) | resource | |
| 274 | +| [aws_iam_policy_document.firehose](https://registry.terraform.io/providers/hashicorp/aws/4.9.0/docs/data-sources/iam_policy_document) | data source | |
| 275 | + |
| 276 | +---- |
| 277 | +<!-- END_TF_DOCS --> |
0 commit comments