runner-binaries-syncer.tf 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. locals {
  2. lambda_zip = var.lambda_zip == null ? "${path.module}/lambdas/runner-binaries-syncer/runner-binaries-syncer.zip" : var.lambda_zip
  3. role_path = var.role_path == null ? "/${var.prefix}/" : var.role_path
  4. gh_binary_os_label = {
  5. windows = "win",
  6. linux = "linux"
  7. }
  8. }
  9. # tfsec:ignore:aws-lambda-enable-tracing We do not enable X-Ray Tracing for Lambda
  10. resource "aws_lambda_function" "syncer" {
  11. # checkov:skip=CKV_AWS_50: see tfsec ignore X-Ray Tracing
  12. s3_bucket = var.lambda_s3_bucket != null ? var.lambda_s3_bucket : null
  13. s3_key = var.syncer_lambda_s3_key != null ? var.syncer_lambda_s3_key : null
  14. s3_object_version = var.syncer_lambda_s3_object_version != null ? var.syncer_lambda_s3_object_version : null
  15. filename = var.lambda_s3_bucket == null ? local.lambda_zip : null
  16. source_code_hash = var.lambda_s3_bucket == null ? filebase64sha256(local.lambda_zip) : null
  17. function_name = "${var.prefix}-syncer"
  18. role = aws_iam_role.syncer_lambda.arn
  19. handler = "index.handler"
  20. runtime = var.lambda_runtime
  21. timeout = var.lambda_timeout
  22. memory_size = 256
  23. #architectures = [var.lambda_architecture]
  24. architectures = var.lambda_architecture == "x86_64" ? [] : [var.lambda_architecture]
  25. environment {
  26. variables = {
  27. GITHUB_RUNNER_ALLOW_PRERELEASE_BINARIES = var.runner_allow_prerelease_binaries
  28. GITHUB_RUNNER_ARCHITECTURE = var.runner_architecture
  29. GITHUB_RUNNER_OS = local.gh_binary_os_label[var.runner_os]
  30. LOG_LEVEL = var.log_level
  31. LOG_TYPE = var.log_type
  32. S3_BUCKET_NAME = aws_s3_bucket.action_dist.id
  33. S3_OBJECT_KEY = local.action_runner_distribution_object_key
  34. S3_SSE_ALGORITHM = try(var.server_side_encryption_configuration.rule.apply_server_side_encryption_by_default.sse_algorithm, null)
  35. S3_SSE_KMS_KEY_ID = try(var.server_side_encryption_configuration.rule.apply_server_side_encryption_by_default.kms_master_key_id, null)
  36. }
  37. }
  38. dynamic "vpc_config" {
  39. for_each = var.lambda_subnet_ids != null && var.lambda_security_group_ids != null ? [true] : []
  40. content {
  41. security_group_ids = var.lambda_security_group_ids
  42. subnet_ids = var.lambda_subnet_ids
  43. }
  44. }
  45. tags = var.tags
  46. }
  47. resource "aws_iam_role_policy" "lambda_kms" {
  48. count = try(var.server_side_encryption_configuration.rule.apply_server_side_encryption_by_default.kms_master_key_id, null) != null ? 1 : 0
  49. name = "${var.prefix}-lambda-kms-policy-syncer"
  50. role = aws_iam_role.syncer_lambda.id
  51. policy = templatefile("${path.module}/policies/lambda-kms.json", {
  52. kms_key_arn = var.server_side_encryption_configuration.rule.apply_server_side_encryption_by_default.kms_master_key_id
  53. })
  54. }
  55. resource "aws_cloudwatch_log_group" "syncer" {
  56. name = "/aws/lambda/${aws_lambda_function.syncer.function_name}"
  57. retention_in_days = var.logging_retention_in_days
  58. kms_key_id = var.logging_kms_key_id
  59. tags = var.tags
  60. }
  61. resource "aws_iam_role" "syncer_lambda" {
  62. name = "${var.prefix}-action-syncer-lambda-role"
  63. assume_role_policy = data.aws_iam_policy_document.lambda_assume_role_policy.json
  64. path = local.role_path
  65. permissions_boundary = var.role_permissions_boundary
  66. tags = var.tags
  67. }
  68. data "aws_iam_policy_document" "lambda_assume_role_policy" {
  69. statement {
  70. actions = ["sts:AssumeRole"]
  71. principals {
  72. type = "Service"
  73. identifiers = ["lambda.amazonaws.com"]
  74. }
  75. dynamic "principals" {
  76. for_each = var.lambda_principals
  77. content {
  78. type = principals.value.type
  79. identifiers = principals.value.identifiers
  80. }
  81. }
  82. }
  83. }
  84. resource "aws_iam_role_policy" "lambda_logging" {
  85. name = "${var.prefix}-lambda-logging-policy-syncer"
  86. role = aws_iam_role.syncer_lambda.id
  87. policy = templatefile("${path.module}/policies/lambda-cloudwatch.json", {
  88. log_group_arn = aws_cloudwatch_log_group.syncer.arn
  89. })
  90. }
  91. resource "aws_iam_role_policy" "syncer" {
  92. name = "${var.prefix}-lambda-syncer-s3-policy"
  93. role = aws_iam_role.syncer_lambda.id
  94. policy = templatefile("${path.module}/policies/lambda-syncer.json", {
  95. s3_resource_arn = "${aws_s3_bucket.action_dist.arn}/${local.action_runner_distribution_object_key}"
  96. })
  97. }
  98. resource "aws_cloudwatch_event_rule" "syncer" {
  99. name = "${var.prefix}-syncer-rule"
  100. schedule_expression = var.lambda_schedule_expression
  101. tags = var.tags
  102. }
  103. resource "aws_cloudwatch_event_target" "syncer" {
  104. rule = aws_cloudwatch_event_rule.syncer.name
  105. arn = aws_lambda_function.syncer.arn
  106. }
  107. resource "aws_lambda_permission" "syncer" {
  108. statement_id = "AllowExecutionFromCloudWatch"
  109. action = "lambda:InvokeFunction"
  110. function_name = aws_lambda_function.syncer.function_name
  111. principal = "events.amazonaws.com"
  112. source_arn = aws_cloudwatch_event_rule.syncer.arn
  113. }
  114. ###################################################################################
  115. ### Extra trigger to trigger from S3 to execute the lambda after first deployment
  116. ###################################################################################
  117. resource "aws_s3_object" "trigger" {
  118. bucket = aws_s3_bucket.action_dist.id
  119. key = "triggers/${aws_lambda_function.syncer.id}-trigger.json"
  120. source = "${path.module}/trigger.json"
  121. etag = try(var.server_side_encryption_configuration.rule.apply_server_side_encryption_by_default.kms_master_key_id, null) == null ? filemd5("${path.module}/trigger.json") : null
  122. kms_key_id = try(var.server_side_encryption_configuration.rule.apply_server_side_encryption_by_default.kms_master_key_id, null)
  123. server_side_encryption = try(var.server_side_encryption_configuration.rule.apply_server_side_encryption_by_default.sse_algorithm, null)
  124. depends_on = [aws_s3_bucket_notification.on_deploy]
  125. }
  126. resource "aws_s3_bucket_notification" "on_deploy" {
  127. bucket = aws_s3_bucket.action_dist.id
  128. lambda_function {
  129. lambda_function_arn = aws_lambda_function.syncer.arn
  130. events = ["s3:ObjectCreated:*"]
  131. filter_prefix = "triggers/"
  132. filter_suffix = ".json"
  133. }
  134. depends_on = [aws_lambda_permission.on_deploy]
  135. }
  136. data "aws_caller_identity" "current" {}
  137. resource "aws_lambda_permission" "on_deploy" {
  138. statement_id = "AllowExecutionFromS3Bucket"
  139. action = "lambda:InvokeFunction"
  140. function_name = aws_lambda_function.syncer.arn
  141. principal = "s3.amazonaws.com"
  142. source_account = data.aws_caller_identity.current.account_id
  143. source_arn = aws_s3_bucket.action_dist.arn
  144. }