main.tf 9.2 KB

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