@@ -128,4 +128,283 @@ HTTP sources can be imported using the collector name and source name (`collecto
128128terraform import sumologic_kinesis_metrics_source.test my-test-collector/my-test-source
129129```
130130
131+ ## Full Example (Including terraform for AWS asset creation)
132+ ``` hcl
133+ terraform {
134+ required_providers {
135+ sumologic = {
136+ source = "sumologic/sumologic"
137+ }
138+ aws = {
139+ source = "hashicorp/aws"
140+ }
141+ }
142+ }
143+
144+ provider "sumologic" {}
145+ provider "aws" {}
146+
147+ locals {
148+ account_id = ""
149+ aws_access_key = ""
150+ aws_secret_key = ""
151+
152+ description = "update your terraform description here"
153+ identifier = "SumologicMetricStream"
154+
155+ region = "us-west-2"
156+
157+ tagfilters = [
158+ { type = "TagFilters", namespace = "AWS/ApplicationELB", tags = ["Deployment=prod"] },
159+ ]
160+
161+ }
162+
163+ resource "sumologic_collector" "collector_for_kinesis_metrics" {
164+ name = "AWS Metrics via Kinesis"
165+ }
166+
167+ resource "sumologic_kinesis_metrics_source" "kinesis_source" {
168+ name = "CloudWatch Metrics via Kinesis"
169+ description = "Description for Sumologic source"
170+ category = "aws/cloudwatch"
171+ content_type = "KinesisMetric"
172+ collector_id = sumologic_collector.collector_for_kinesis_metrics.id
173+
174+ authentication {
175+ type = "S3BucketAuthentication"
176+ access_key = local.aws_access_key
177+ secret_key = local.aws_secret_key
178+ }
179+
180+ path {
181+ type = "KinesisMetricPath"
182+
183+ dynamic "tag_filters" {
184+ for_each = local.tagfilters
185+ content {
186+ type = tag_filters.value.type
187+ namespace = tag_filters.value.namespace
188+ tags = tag_filters.value.tags
189+ }
190+ }
191+ }
192+ }
193+
194+ // ------------------------------------ AWS Kinesis part
195+
196+ resource "aws_cloudwatch_metric_stream" "main" {
197+ name = local.identifier
198+ role_arn = aws_iam_role.metric_stream_to_firehose.arn
199+ firehose_arn = aws_kinesis_firehose_delivery_stream.kinesis_stream.arn
200+ output_format = "opentelemetry0.7"
201+
202+ // Edit and uncomment below lines to add include_filter (or exclude_filter on similar lines)
203+ // include_filter {
204+ // namespace = "AWS/ApplicationELB"
205+ // }
206+ // include_filter {
207+ // namespace = "AWS/DynamoDB"
208+ // }
209+
210+ }
211+
212+ resource "aws_iam_role" "metric_stream_to_firehose" {
213+ name = "${local.identifier}-stream_to_firehose"
214+
215+ assume_role_policy = <<EOF
216+ {
217+ "Version": "2012-10-17",
218+ "Statement": [
219+ {
220+ "Action": "sts:AssumeRole",
221+ "Principal": {
222+ "Service": "streams.metrics.cloudwatch.amazonaws.com"
223+ },
224+ "Effect": "Allow",
225+ "Sid": ""
226+ }
227+ ]
228+ }
229+ EOF
230+ }
231+
232+ resource "aws_iam_role_policy" "metric_stream_to_firehose" {
233+ name = "default"
234+ role = aws_iam_role.metric_stream_to_firehose.id
235+
236+ policy = <<EOF
237+ {
238+ "Version": "2012-10-17",
239+ "Statement": [
240+ {
241+ "Effect": "Allow",
242+ "Action": [
243+ "firehose:PutRecord",
244+ "firehose:PutRecordBatch"
245+ ],
246+ "Resource": "${aws_kinesis_firehose_delivery_stream.kinesis_stream.arn}"
247+ }
248+ ]
249+ }
250+ EOF
251+ }
252+
253+ resource "aws_iam_role" "firehose_role" {
254+ name = "${local.identifier}_firehose"
255+
256+ assume_role_policy = <<EOF
257+ {
258+ "Version": "2012-10-17",
259+ "Statement": [
260+ {
261+ "Action": "sts:AssumeRole",
262+ "Principal": {
263+ "Service": "firehose.amazonaws.com"
264+ },
265+ "Effect": "Allow",
266+ "Sid": ""
267+ }
268+ ]
269+ }
270+ EOF
271+ }
272+
273+ resource "aws_iam_role_policy" "firehose_can_log_errors_to_Cloudwatch" {
274+ role = aws_iam_role.firehose_role.id
275+
276+ policy = <<EOF
277+ {
278+ "Version": "2012-10-17",
279+ "Statement": [
280+ {
281+ "Effect": "Allow",
282+ "Action": [
283+ "logs:PutLogEvents"
284+ ],
285+ "Resource": [
286+ "arn:aws:logs:${local.region}:${local.account_id}:log-group:/aws/kinesisfirehose/${local.identifier}:*",
287+ "arn:aws:logs:${local.region}:${local.account_id}:log-group:/aws/kinesisfirehose/${local.identifier}:*:log-stream:*"
288+ ]
289+ }
290+ ]
291+ }
292+ EOF
293+ }
294+
295+ resource "aws_iam_role_policy" "firehose_can_use_s3_bucket_for_failures" {
296+ role = aws_iam_role.firehose_role.id
297+
298+ policy = <<EOF
299+ {
300+ "Version": "2012-10-17",
301+ "Statement": [
302+ {
303+ "Action": [
304+ "s3:AbortMultipartUpload",
305+ "s3:GetBucketLocation",
306+ "s3:GetObject",
307+ "s3:ListBucket",
308+ "s3:ListBucketMultipartUploads",
309+ "s3:PutObject"
310+ ],
311+ "Resource": [
312+ "arn:aws:s3:::${aws_s3_bucket.bucket_for_Kinesis_failures.bucket}/*",
313+ "arn:aws:s3:::${aws_s3_bucket.bucket_for_Kinesis_failures.bucket}"
314+ ],
315+ "Effect": "Allow"
316+ }
317+ ]
318+ }
319+ EOF
320+ }
321+
322+ resource "aws_s3_bucket" "bucket_for_Kinesis_failures" {
323+ bucket = "${replace(lower(local.identifier),"_", "-")}-kinesisfailures"
324+ }
325+ resource "aws_s3_bucket_acl" "bucket_for_Kinesis_failures" {
326+ bucket = aws_s3_bucket.bucket_for_Kinesis_failures.id
327+ acl = "private"
328+ }
329+ resource "aws_kinesis_firehose_delivery_stream" "kinesis_stream" {
330+ name = local.identifier
331+ destination = "http_endpoint"
332+
333+ http_endpoint_configuration {
334+ name = "ToSumo"
335+ url = sumologic_kinesis_metrics_source.kinesis_source.url
336+ role_arn = aws_iam_role.firehose_role.arn
337+ buffering_interval = 60
338+ s3_backup_mode = "FailedDataOnly"
339+
340+ request_configuration {
341+ content_encoding = "GZIP"
342+ }
343+
344+ cloudwatch_logging_options {
345+ enabled = true
346+ log_group_name = "/aws/kinesisfirehose/${local.identifier}"
347+ log_stream_name = "DestinationDelivery"
348+ }
349+ }
350+
351+ s3_configuration {
352+ role_arn = aws_iam_role.firehose_role.arn
353+ bucket_arn = aws_s3_bucket.bucket_for_Kinesis_failures.arn
354+ }
355+ }
356+
357+
358+ // ------------------------------------ authorizing Sumo to use our AWS accounts
359+
360+ resource "aws_iam_policy" "cloudwatch_ingest" {
361+ name = "policy-for-cloudwatch-ingest"
362+ description = "Managed by Terraform"
363+
364+ policy = <<EOF
365+ {
366+ "Version": "2012-10-17",
367+ "Statement": [
368+ {
369+ "Action": [
370+ "cloudwatch:ListMetrics",
371+ "cloudwatch:GetMetricStatistics",
372+ "tag:GetResources"
373+ ],
374+ "Effect": "Allow",
375+ "Resource": "*"
376+ }
377+ ]
378+ }
379+ EOF
380+ }
381+
382+ data "aws_iam_policy_document" "sumo_can_use_our_AWS" {
383+ statement {
384+ actions = ["sts:AssumeRole"]
385+ condition {
386+ test = "StringEquals"
387+ variable = "sts:ExternalId"
388+ values = [local.account_id]
389+ }
390+ principals {
391+ identifiers = ["arn:aws:iam::${local.account_id}:root"]
392+ type = "AWS"
393+ }
394+ }
395+ }
396+
397+ resource "aws_iam_role" "cloudwatch_role" {
398+ name = "role-for-cloudwatch-ingest"
399+ assume_role_policy = data.aws_iam_policy_document.sumo_can_use_our_AWS.json
400+ }
401+
402+ resource "aws_iam_role_policy_attachment" "test-attach" {
403+ role = aws_iam_role.cloudwatch_role.name
404+ policy_arn = aws_iam_policy.cloudwatch_ingest.arn
405+ }
406+
407+ ```
408+
409+
131410[ 1 ] : https://help.sumologic.com/Send_Data/Sources/03Use_JSON_to_Configure_Sources/JSON_Parameters_for_Hosted_Sources
0 commit comments