codebuild.tf 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #-----------------------------------------------------------------------
  2. # Common AssumeRole policy for these codebuild roles
  3. #-----------------------------------------------------------------------
  4. data "aws_iam_policy_document" "codebuild_role_assume_role_policy" {
  5. statement {
  6. effect = "Allow"
  7. actions = [
  8. "sts:AssumeRole"
  9. ]
  10. principals {
  11. type = "Service"
  12. identifiers = [
  13. "codebuild.amazonaws.com",
  14. "events.amazonaws.com"
  15. ]
  16. }
  17. }
  18. }
  19. #-----------------------------------------------------------------------
  20. # "Basic" Codebuild Role - not capable to make EC2 images / run Packer
  21. #-----------------------------------------------------------------------
  22. resource "aws_iam_role" "codebuild_basic_role" {
  23. name = "codebuild_basic_role"
  24. path = "/aws_services/"
  25. assume_role_policy = data.aws_iam_policy_document.codebuild_role_assume_role_policy.json
  26. }
  27. resource "aws_iam_role_policy_attachment" "codebuild_basic_role_basic_policy_attach" {
  28. role = aws_iam_role.codebuild_basic_role.name
  29. policy_arn = aws_iam_policy.codebuild_basic_policy.arn
  30. }
  31. #-----------------------------------------------------------------------
  32. # "Packer" Codebuild Role
  33. #-----------------------------------------------------------------------
  34. resource "aws_iam_role" "codebuild_packer_role" {
  35. name = "codebuild_packer_role"
  36. path = "/aws_services/"
  37. assume_role_policy = data.aws_iam_policy_document.codebuild_role_assume_role_policy.json
  38. }
  39. # Packer role needs basic role too for things like cloudwatch
  40. resource "aws_iam_role_policy_attachment" "codebuild_packer_role_basic_policy_attach" {
  41. role = aws_iam_role.codebuild_packer_role.name
  42. policy_arn = aws_iam_policy.codebuild_basic_policy.arn
  43. }
  44. resource "aws_iam_role_policy_attachment" "codebuild_packer_role_packer_policy_attach" {
  45. role = aws_iam_role.codebuild_packer_role.name
  46. policy_arn = aws_iam_policy.codebuild_build_ec2_amis_policy.arn
  47. }
  48. #-----------------------------------------------------------------------
  49. # "Basic" Policy for codebuild - can make artifacts and ECR images but not EC2
  50. # FIXME: Not sure about this policy
  51. # 2. Lets codebuild (apparently) write to ANY ECR repo
  52. # 4. Latest codebuild policies (from AWS console) have report-group resources and actions
  53. #-----------------------------------------------------------------------
  54. resource "aws_iam_policy" "codebuild_basic_policy" {
  55. name = "codebuild_basic_policy"
  56. path = "/aws_services/"
  57. description = "Policy for AWS codebuild to build AMIs"
  58. policy = data.aws_iam_policy_document.codebuild_base_policy.json
  59. }
  60. data "aws_iam_policy_document" "codebuild_base_policy" {
  61. # checkov:skip=CKV_AWS_111: see tfsec aws-iam-no-policy-wildcard ignore comment
  62. statement {
  63. sid = "WriteCodebuildLogsToCloudwatchLogs"
  64. effect = "Allow"
  65. resources = [
  66. "arn:${local.aws_partition}:logs:${local.aws_region}:${local.aws_account}:log-group:/aws/codebuild/*"
  67. ]
  68. actions = [
  69. "logs:CreateLogGroup",
  70. "logs:CreateLogStream",
  71. "logs:PutLogEvents"
  72. ]
  73. }
  74. # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account
  75. statement {
  76. sid = "StoreArtifactsInBucket"
  77. effect = "Allow"
  78. resources = [
  79. "arn:${local.aws_partition}:s3:::xdr-codebuild-artifacts/*"
  80. ]
  81. actions = [
  82. "s3:PutObject",
  83. "s3:GetObject*",
  84. "s3:ListBucket"
  85. ]
  86. }
  87. # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account
  88. statement {
  89. sid = "UpdateECRRepos"
  90. effect = "Allow"
  91. resources = [
  92. "*"
  93. ]
  94. actions = [
  95. "ecr:GetAuthorizationToken",
  96. "ecr:BatchCheckLayerAvailability",
  97. "ecr:CompleteLayerUpload",
  98. "ecr:GetAuthorizationToken",
  99. "ecr:InitiateLayerUpload",
  100. "ecr:PutImage",
  101. "ecr:UploadLayerPart"
  102. ]
  103. }
  104. # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account
  105. statement {
  106. sid = "LetEventBridgeTriggerABuild"
  107. effect = "Allow"
  108. resources = [
  109. "*"
  110. ]
  111. actions = [
  112. "codebuild:StartBuild",
  113. "codebuild:StopBuild",
  114. "codebuild:BatchGet*",
  115. "codebuild:Get*",
  116. "codebuild:List*"
  117. ]
  118. }
  119. }
  120. #-----------------------------------------------------------------------
  121. # "EC2" Policy for codebuild - able to build EC2 images / SGs / etc
  122. # FIXME: too powerful
  123. #
  124. # Parts of this are Lifted from
  125. # https://www.packer.io/plugins/builders/amazon#iam-task-or-instance-role and
  126. # converted from JSON to a terraform data source NOT AUDITED - taking Packer
  127. # docs at word that these are "minimal permissions necessary"
  128. #
  129. # The rest is for EBS+KMS support cobbled from AWS docs
  130. #-----------------------------------------------------------------------
  131. resource "aws_iam_policy" "codebuild_build_ec2_amis_policy" {
  132. name = "codebuild_build_ami_policy"
  133. path = "/aws_services/"
  134. description = "Policy for AWS codebuild to build AMIs"
  135. policy = data.aws_iam_policy_document.codebuild_build_ec2_amis.json
  136. }
  137. data "aws_iam_policy_document" "codebuild_build_ec2_amis" {
  138. # checkov:skip=CKV_AWS_107: IAM policies does not allow credentials exposure for ECR
  139. # checkov:skip=CKV_AWS_109: see tfsec aws-iam-no-policy-wildcard ignore comment
  140. # checkov:skip=CKV_AWS_110: IAM policies does not allow privilege escalation
  141. # checkov:skip=CKV_AWS_111: see tfsec aws-iam-no-policy-wildcard ignore comment
  142. # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account
  143. statement {
  144. sid = "BuildEC2AMIFromPackerDocs"
  145. effect = "Allow"
  146. resources = [ "*" ]
  147. actions = [
  148. "ec2:AttachVolume",
  149. "ec2:AuthorizeSecurityGroupIngress",
  150. "ec2:CopyImage",
  151. "ec2:CreateImage",
  152. "ec2:CreateKeypair",
  153. "ec2:CreateSecurityGroup",
  154. "ec2:CreateSnapshot",
  155. "ec2:CreateTags",
  156. "ec2:CreateVolume",
  157. "ec2:CreateNetworkInterface",
  158. "ec2:CreateNetworkInterfacePermission",
  159. "ec2:DeleteKeyPair",
  160. "ec2:DeleteNetworkInterface",
  161. "ec2:DeleteSecurityGroup",
  162. "ec2:DeleteSnapshot",
  163. "ec2:DeleteVolume",
  164. "ec2:DeregisterImage",
  165. "ec2:Describe*",
  166. "ec2:DetachVolume",
  167. "ec2:GetPasswordData",
  168. "ec2:ModifyImageAttribute",
  169. "ec2:ModifyInstanceAttribute",
  170. "ec2:ModifySnapshotAttribute",
  171. "ec2:RegisterImage",
  172. "ec2:RunInstances",
  173. "ec2:StopInstances",
  174. "ec2:TerminateInstances"
  175. ]
  176. }
  177. statement {
  178. sid = "BuildEC2WithInstanceRole"
  179. effect = "Allow"
  180. # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account
  181. resources = [ "*" ]
  182. actions = [
  183. "iam:PassRole"
  184. ]
  185. }
  186. statement {
  187. sid = "PullFromSecretsManager"
  188. effect = "Allow"
  189. resources = [
  190. "arn:${local.aws_partition}:secretsmanager:${local.aws_region}:${local.aws_account}:secret:msoc-build*",
  191. "arn:${local.aws_partition}:secretsmanager:${local.aws_region}:${local.aws_account}:secret:mdr-aws-codebuild*"
  192. ]
  193. actions = [
  194. "secretsmanager:GetSecretValue"
  195. ]
  196. }
  197. # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account
  198. statement {
  199. sid = "KMSAccessNeededForEBS"
  200. effect = "Allow"
  201. resources = [ "*" ]
  202. actions = [
  203. "kms:RevokeGrant",
  204. "kms:ListGrants",
  205. "kms:Decrypt",
  206. "kms:DescribeKey",
  207. "kms:GenerateDataKeyWithoutPlainText",
  208. "kms:ReEncrypt*",
  209. ]
  210. }
  211. # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account
  212. statement {
  213. sid = "SSMCodeBuildPause"
  214. effect = "Allow"
  215. resources = [ "*" ]
  216. actions = [
  217. "ssmmessages:CreateControlChannel",
  218. "ssmmessages:CreateDataChannel",
  219. "ssmmessages:OpenControlChannel",
  220. "ssmmessages:OpenDataChannel"
  221. ]
  222. }
  223. # tfsec:ignore:aws-iam-no-policy-wildcards Allows use by the entire account
  224. statement {
  225. sid = "CreateGrantForEBS"
  226. effect = "Allow"
  227. resources = ["*"]
  228. actions = [
  229. "kms:CreateGrant",
  230. ]
  231. condition {
  232. test = "Bool"
  233. variable = "kms:GrantIsForAWSResource"
  234. values = ["true"]
  235. }
  236. }
  237. }