data "aws_iam_policy_document" "lambda_deployment_policy" {
  version = "2012-10-17"
  statement {
    sid    = "AllowListOfMyS3Buckets"
    effect = "Allow"
    actions = [
      "s3:GetBucketNotification",
      "s3:HeadBucket",
      "s3:ListAllMyBuckets",
      "s3:PutBucketNotification",
    ]
    resources = ["*"]
  }

  statement {
    sid    = "AllowListOfS3Bucket"
    effect = "Allow"
    actions = [
      "s3:ListBucket",
    ]
    resources = ["arn:aws:s3:::*-lambda-artifacts"]
  }

  statement {
    sid    = "AllowReadWriteS3"
    effect = "Allow"
    actions = [
      "s3:GetObject",
      "s3:GetBucketLocation",
      "s3:GetObjectTagging",
      "s3:GetObjectVersion",
      "s3:GetObjectVersionTagging",
      "s3:ListMultipartUploadParts",
      "s3:AbortMultipartUpload",
      "s3:ListBucketMultipartUploads",
      "s3:PutObjectVersionTagging",
      "s3:PutObjectTagging",
      "s3:PutObject",
      "s3:PutObjectAcl",
    ]
    resources = [
      "arn:aws:s3:::*-lambda-artifacts",
      "arn:aws:s3:::*-lambda-artifacts/*"
    ]
  }

  statement {
    sid    = "AllowGetPassRoleLambda"
    effect = "Allow"
    actions = [
      "iam:GetRole",
      "iam:PassRole"
    ]
    resources = ["arn:aws:iam::*:role/*"]
  }

  statement {
    sid    = "AllowReadWriteEventBus"
    effect = "Allow"
    actions = [
      "events:DeleteRule",
      "events:DescribeRule",
      "events:DisableRule",
      "events:EnableRule",
      "events:ListRuleNamesByTarget",
      "events:ListTagsForResource",
      "events:ListTargetsByRule",
      "events:PutRule",
      "events:PutTargets",
      "events:RemoveTargets",
    ]
    resources = ["arn:aws:events:${local.region}:${local.account_id}:rule/*"]
  }

  statement {
    sid    = "AllowCreateUpdateLambda"
    effect = "Allow"
    actions = [
      "lambda:AddPermission",
      "lambda:CreateFunction",
      "lambda:GetAlias",
      "lambda:GetFunction",
      "lambda:GetFunctionConfiguration",
      "lambda:GetPolicy",
      "lambda:RemovePermission",
      "lambda:TagResource",
      "lambda:UpdateFunctionCode",
      "lambda:UpdateFunctionConfiguration",
      "lambda:InvokeFunction",
    ]
    resources = ["arn:aws:lambda:${local.region}:${local.account_id}:function:*"]
  }

  statement {
    sid    = "AllowLambdaLayers"
    effect = "Allow"
    actions = [
      "lambda:AddLayerVersionPermission",
      "lambda:PublishLayerVersion",
      "lambda:RemoveLayerVersionPermission",
    ]
    resources = ["arn:aws:lambda:${local.region}:${local.account_id}:layer:*"]
  }

  statement {
    sid    = "AllowPublicLambdaLayers"
    effect = "Allow"
    actions = [
      "lambda:GetLayerVersion",
      "lambda:ListLayerVersions",
      "lambda:ListLayers",
    ]
    resources = ["*"]
  }

  statement {
    sid    = "AllowListDescribe"
    effect = "Allow"
    actions = [
      "ec2:DescribeSecurityGroups",
      "ec2:DescribeSubnets",
      "ec2:DescribeVpcs",
      "lambda:CreateEventSourceMapping",
      "lambda:ListEventSourceMappings",
      "lambda:ListVersionsByFunction",
      "lambda:GetLayerVersion",
    ]
    resources = ["*"]
  }

  statement {
    sid    = "AlloDeletionAndConcurrencyChanges"
    effect = "Allow"
    actions = [
      "lambda:DeleteFunction",
      "lambda:DeleteFunctionConcurrency",
      "lambda:PutFunctionConcurrency",
      "lambda:PutProvisionedConcurrencyConfig",
    ]
    resources = ["arn:aws:lambda:${local.region}:${local.account_id}:function:*"]
  }

  statement {
    sid    = "AllowUsingKMSKeysViaLambdaService"
    effect = "Allow"
    actions = [
      "kms:CreateGrant",
      "kms:Decrypt",
      "kms:DescribeKey",
      "kms:Encrypt",
      "kms:GenerateDataKey*",
    ]
    condition {
      test     = "StringLike"
      variable = "kms:ViaService"
      values   = ["lambda.${local.region}.amazonaws.com"]
    }
    resources = ["*"]
  }
}

resource "aws_iam_policy" "lambda_deployment_policy" {
  name        = "${var.name_prefix}-lambda_deploy_policy"
  path        = "/"
  description = "Allows to upload files to a specific buckets and update lambda functions code"
  policy      = data.aws_iam_policy_document.lambda_deployment_policy.json
}
