main.tf 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. # Kenisis firehose stream
  2. # Record Transformation Required, called "processing_configuration" in Terraform
  3. resource "aws_kinesis_firehose_delivery_stream" "kinesis_firehose" {
  4. name = var.firehose_name
  5. destination = "splunk"
  6. s3_configuration {
  7. role_arn = aws_iam_role.kinesis_firehose.arn
  8. prefix = var.s3_prefix
  9. bucket_arn = aws_s3_bucket.kinesis_firehose_s3_bucket.arn
  10. buffer_size = var.kinesis_firehose_buffer
  11. buffer_interval = var.kinesis_firehose_buffer_interval
  12. compression_format = var.s3_compression_format
  13. }
  14. splunk_configuration {
  15. hec_endpoint = var.hec_url
  16. hec_token = var.hec_token
  17. hec_acknowledgment_timeout = var.hec_acknowledgment_timeout
  18. hec_endpoint_type = var.hec_endpoint_type
  19. s3_backup_mode = var.s3_backup_mode
  20. processing_configuration {
  21. enabled = "true"
  22. processors {
  23. type = "Lambda"
  24. parameters {
  25. parameter_name = "LambdaArn"
  26. parameter_value = "${aws_lambda_function.firehose_lambda_transform.arn}:$LATEST"
  27. }
  28. parameters {
  29. parameter_name = "RoleArn"
  30. parameter_value = aws_iam_role.kinesis_firehose.arn
  31. }
  32. }
  33. }
  34. cloudwatch_logging_options {
  35. enabled = var.enable_fh_cloudwatch_logging
  36. log_group_name = aws_cloudwatch_log_group.kinesis_logs.name
  37. log_stream_name = aws_cloudwatch_log_stream.kinesis_logs.name
  38. }
  39. }
  40. tags = var.tags
  41. }
  42. # S3 Bucket for Kinesis Firehose s3_backup_mode
  43. resource "aws_s3_bucket" "kinesis_firehose_s3_bucket" {
  44. bucket = var.s3_bucket_name
  45. tags = var.tags
  46. }
  47. resource "aws_s3_bucket_acl" "kinesis_firehose_s3_bucket" {
  48. bucket = aws_s3_bucket.kinesis_firehose_s3_bucket.id
  49. acl = "private"
  50. }
  51. resource "aws_s3_bucket_server_side_encryption_configuration" "kinesis_firehose_s3_bucket" {
  52. bucket = aws_s3_bucket.kinesis_firehose_s3_bucket.id
  53. rule {
  54. apply_server_side_encryption_by_default {
  55. sse_algorithm = "AES256"
  56. }
  57. }
  58. }
  59. resource "aws_s3_bucket_lifecycle_configuration" "kinesis_firehose_s3_bucket" {
  60. bucket = aws_s3_bucket.kinesis_firehose_s3_bucket.id
  61. rule {
  62. id = "expire-old-logs"
  63. status = "Enabled"
  64. filter {
  65. prefix = ""
  66. }
  67. expiration {
  68. days = var.s3_expiration
  69. }
  70. noncurrent_version_expiration {
  71. noncurrent_days = var.s3_expiration
  72. }
  73. abort_incomplete_multipart_upload {
  74. days_after_initiation = 7
  75. }
  76. }
  77. }
  78. resource "aws_s3_bucket_public_access_block" "kinesis_firehose_s3_bucket" {
  79. count = var.s3_bucket_block_public_access_enabled
  80. bucket = aws_s3_bucket.kinesis_firehose_s3_bucket.id
  81. block_public_acls = true
  82. block_public_policy = true
  83. ignore_public_acls = true
  84. restrict_public_buckets = true
  85. }
  86. # Cloudwatch logging group for Kinesis Firehose
  87. resource "aws_cloudwatch_log_group" "kinesis_logs" {
  88. name = "/aws/kinesisfirehose/${var.firehose_name}"
  89. retention_in_days = var.cloudwatch_log_retention
  90. tags = var.tags
  91. }
  92. # Create the stream
  93. resource "aws_cloudwatch_log_stream" "kinesis_logs" {
  94. name = var.log_stream_name
  95. log_group_name = aws_cloudwatch_log_group.kinesis_logs.name
  96. }
  97. ## handle the sensitivity of the hec_token variable
  98. #data "aws_kms_secrets" "splunk_hec_token" {
  99. # secret {
  100. # name = "hec_token"
  101. # payload = var.hec_token
  102. #
  103. # context = var.encryption_context
  104. # }
  105. #}
  106. # Role for the transformation Lambda function attached to the kinesis stream
  107. resource "aws_iam_role" "kinesis_firehose_lambda" {
  108. name = var.kinesis_firehose_lambda_role_name
  109. path = "/lambda/"
  110. description = "Role for Lambda function to transformation CloudWatch logs into Splunk compatible format"
  111. force_detach_policies = true
  112. assume_role_policy = <<POLICY
  113. {
  114. "Statement": [
  115. {
  116. "Effect": "Allow",
  117. "Action": "sts:AssumeRole",
  118. "Principal": {
  119. "Service": "lambda.amazonaws.com"
  120. }
  121. }
  122. ],
  123. "Version": "2012-10-17"
  124. }
  125. POLICY
  126. tags = var.tags
  127. }
  128. data "aws_iam_policy_document" "lambda_policy_doc" {
  129. statement {
  130. actions = [
  131. "logs:GetLogEvents",
  132. ]
  133. resources = [
  134. var.arn_cloudwatch_logs_to_ship,
  135. ]
  136. effect = "Allow"
  137. }
  138. statement {
  139. actions = [
  140. "firehose:PutRecordBatch",
  141. ]
  142. resources = [
  143. aws_kinesis_firehose_delivery_stream.kinesis_firehose.arn,
  144. ]
  145. }
  146. statement {
  147. actions = [
  148. "logs:PutLogEvents",
  149. ]
  150. resources = [
  151. "*",
  152. ]
  153. effect = "Allow"
  154. }
  155. statement {
  156. actions = [
  157. "logs:CreateLogGroup",
  158. ]
  159. resources = [
  160. "*",
  161. ]
  162. effect = "Allow"
  163. }
  164. statement {
  165. actions = [
  166. "logs:CreateLogStream",
  167. ]
  168. resources = [
  169. "*",
  170. ]
  171. effect = "Allow"
  172. }
  173. }
  174. resource "aws_iam_policy" "lambda_transform_policy" {
  175. name = var.lambda_iam_policy_name
  176. policy = data.aws_iam_policy_document.lambda_policy_doc.json
  177. }
  178. resource "aws_iam_role_policy_attachment" "lambda_policy_role_attachment" {
  179. role = aws_iam_role.kinesis_firehose_lambda.name
  180. policy_arn = aws_iam_policy.lambda_transform_policy.arn
  181. }
  182. # Create the lambda function
  183. # The lambda function to transform data from compressed format in Cloudwatch to something Splunk can handle (uncompressed)
  184. resource "aws_lambda_function" "firehose_lambda_transform" {
  185. function_name = var.lambda_function_name
  186. description = "Transform data from CloudWatch format to Splunk compatible format"
  187. filename = data.archive_file.lambda_function.output_path
  188. role = aws_iam_role.kinesis_firehose_lambda.arn
  189. handler = "kinesis-firehose-cloudwatch-logs-processor.handler"
  190. source_code_hash = data.archive_file.lambda_function.output_base64sha256
  191. runtime = var.nodejs_runtime
  192. timeout = var.lambda_function_timeout
  193. tags = var.tags
  194. }
  195. # kinesis-firehose-cloudwatch-logs-processor.js was taken by copy/paste from the AWS UI. It is predefined blueprint
  196. # code supplied to AWS by Splunk.
  197. data "archive_file" "lambda_function" {
  198. type = "zip"
  199. source_file = "${path.module}/files/kinesis-firehose-cloudwatch-logs-processor.js"
  200. output_path = "${path.module}/files/kinesis-firehose-cloudwatch-logs-processor.zip"
  201. }
  202. # Role for Kenisis Firehose
  203. resource "aws_iam_role" "kinesis_firehose" {
  204. name = var.kinesis_firehose_role_name
  205. path = "/aws_services/"
  206. description = "IAM Role for Kenisis Firehose"
  207. force_detach_policies = true
  208. assume_role_policy = <<POLICY
  209. {
  210. "Version": "2012-10-17",
  211. "Statement": [
  212. {
  213. "Principal": {
  214. "Service": "firehose.amazonaws.com"
  215. },
  216. "Action": "sts:AssumeRole",
  217. "Effect": "Allow"
  218. }
  219. ]
  220. }
  221. POLICY
  222. tags = var.tags
  223. }
  224. data "aws_iam_policy_document" "kinesis_firehose_policy_document" {
  225. statement {
  226. actions = [
  227. "s3:AbortMultipartUpload",
  228. "s3:GetBucketLocation",
  229. "s3:GetObject",
  230. "s3:ListBucket",
  231. "s3:ListBucketMultipartUploads",
  232. "s3:PutObject",
  233. ]
  234. resources = [
  235. aws_s3_bucket.kinesis_firehose_s3_bucket.arn,
  236. "${aws_s3_bucket.kinesis_firehose_s3_bucket.arn}/*",
  237. ]
  238. effect = "Allow"
  239. }
  240. statement {
  241. actions = [
  242. "lambda:InvokeFunction",
  243. "lambda:GetFunctionConfiguration",
  244. ]
  245. resources = [
  246. "${aws_lambda_function.firehose_lambda_transform.arn}:$LATEST",
  247. ]
  248. }
  249. statement {
  250. actions = [
  251. "logs:PutLogEvents",
  252. ]
  253. resources = [
  254. aws_cloudwatch_log_group.kinesis_logs.arn,
  255. aws_cloudwatch_log_stream.kinesis_logs.arn,
  256. ]
  257. effect = "Allow"
  258. }
  259. }
  260. resource "aws_iam_policy" "kinesis_firehose_iam_policy" {
  261. name = var.kinesis_firehose_iam_policy_name
  262. policy = data.aws_iam_policy_document.kinesis_firehose_policy_document.json
  263. }
  264. resource "aws_iam_role_policy_attachment" "kinesis_fh_role_attachment" {
  265. role = aws_iam_role.kinesis_firehose.name
  266. policy_arn = aws_iam_policy.kinesis_firehose_iam_policy.arn
  267. }
  268. resource "aws_iam_role" "cloudwatch_to_firehose_trust" {
  269. name = var.cloudwatch_to_firehose_trust_iam_role_name
  270. path = "/aws_services/"
  271. description = "Role for CloudWatch Log Group subscription"
  272. force_detach_policies = true
  273. assume_role_policy = <<ROLE
  274. {
  275. "Statement": [
  276. {
  277. "Effect": "Allow",
  278. "Action": "sts:AssumeRole",
  279. "Principal": {
  280. "Service": "logs.${var.region}.amazonaws.com"
  281. }
  282. }
  283. ],
  284. "Version": "2012-10-17"
  285. }
  286. ROLE
  287. }
  288. data "aws_iam_policy_document" "cloudwatch_to_fh_access_policy" {
  289. statement {
  290. actions = [
  291. "firehose:*",
  292. ]
  293. effect = "Allow"
  294. resources = [
  295. aws_kinesis_firehose_delivery_stream.kinesis_firehose.arn,
  296. ]
  297. }
  298. statement {
  299. actions = [
  300. "iam:PassRole",
  301. ]
  302. effect = "Allow"
  303. resources = [
  304. aws_iam_role.cloudwatch_to_firehose_trust.arn,
  305. ]
  306. }
  307. }
  308. resource "aws_iam_policy" "cloudwatch_to_fh_access_policy" {
  309. name = var.cloudwatch_to_fh_access_policy_name
  310. description = "Cloudwatch to Firehose Subscription Policy"
  311. policy = data.aws_iam_policy_document.cloudwatch_to_fh_access_policy.json
  312. }
  313. resource "aws_iam_role_policy_attachment" "cloudwatch_to_fh" {
  314. role = aws_iam_role.cloudwatch_to_firehose_trust.name
  315. policy_arn = aws_iam_policy.cloudwatch_to_fh_access_policy.arn
  316. }
  317. resource "aws_cloudwatch_log_subscription_filter" "cloudwatch_log_filter" {
  318. name = var.cloudwatch_log_filter_name
  319. role_arn = aws_iam_role.cloudwatch_to_firehose_trust.arn
  320. destination_arn = aws_kinesis_firehose_delivery_stream.kinesis_firehose.arn
  321. log_group_name = var.name_cloudwatch_logs_to_ship
  322. filter_pattern = var.subscription_filter_pattern
  323. }