Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat : Aws + Terraform way to deploy this #61

Open
jalotra opened this issue Oct 29, 2024 · 0 comments
Open

Feat : Aws + Terraform way to deploy this #61

jalotra opened this issue Oct 29, 2024 · 0 comments

Comments

@jalotra
Copy link

jalotra commented Oct 29, 2024

hey guys we use terraform with aws in our stack, I deployed this yesterday for our stack and it works fabulously, thanks @iandees and authors, I am giving here a recipe on how to deploy this for a cloud provider using terraform + aws things (lambda and cloudwatch event (for scheduled orchestration).

Steps :

  1. build a docker image out of the repo, we use codebuild to do that (some changes would be needed check lamda python base image)
  2. deploy the lambda which uses the above image
  3. create a aws_cloudwatch_event_rule which schedules this every morning around 5 UTC to trigger these lambdas.

here is recipe for doing this for some account : X

# Lambda to enable sending daily budget updates to slack channel
module "lambda-cost-estimates" {
  source               = "../../modules/lambda"
  lambda_function_name = "cost-estimates-prod"
  ecr_image_uri        = "${local.qa_account_id}.dkr.ecr.${local.aws_region}.amazonaws.com/cost_estimates_lambda_image-nonprod:latest"
  role_statement = [{
    Action = "sts:AssumeRole"
    Principal = {
      Service = "lambda.amazonaws.com"
    }
    Effect = "Allow"
  }]
  policy_statements = [
    {
      Action   = "ce:GetCostAndUsage"
      Effect   = "Allow"
      Resource = "*"
    },
    {
      Action   = "iam:ListAccountAliases"
      Effect   = "Allow"
      Resource = "*"
    }
  ]
  env_vars = {
    "GROUP_BY"          = "SERVICE"
    "SLACK_WEBHOOK_URL" = "<SOME_SLACK_HOOK>"
    "AWS_ACCOUNT_NAME"  = local.account_id
  }
}

resource "aws_cloudwatch_event_rule" "schedule_rule" {
  name                = "cost-schedule-rule"
  schedule_expression = "cron(0 5 * * ? *)"
  description         = "A rule that triggers every day at 5AM UTC"
}

resource "aws_cloudwatch_event_target" "lambda_target" {
  target_id = "1"
  rule      = aws_cloudwatch_event_rule.schedule_rule.name
  arn       = module.lambda-cost-estimates.function_arn
}

resource "aws_lambda_permission" "allow_eventbridge" {
  statement_id  = "scheduled_event"
  action        = "lambda:InvokeFunction"
  function_name = module.lambda-cost-estimates.function_name
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.schedule_rule.arn
}

and this is our lamdba module :

resource "aws_iam_role" "lambda_role" {
  name = "lambda-execution-role"

  assume_role_policy = jsonencode({
    Version   = "2012-10-17"
    Statement = var.role_statement
  })
}

resource "aws_iam_policy" "lambda_execution_policy" {
  name = "lambda-execution-policy"
  policy = jsonencode({
    Version   = "2012-10-17"
    Statement = var.policy_statements
  })
}

locals {
  policy_arns = [
    "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
    aws_iam_policy.lambda_execution_policy.arn
  ]
}

# this adds support for logging / 
resource "aws_iam_policy_attachment" "lambda_policy_attachment" {
  count      = length(local.policy_arns)
  name       = "lambda-policy-${count.index}"
  roles      = [aws_iam_role.lambda_role.name]
  policy_arn = local.policy_arns[count.index]
}

# This is to optionally manage the CloudWatch Log Group for the Lambda Function.
# If skipping this resource configuration, also add "logs:CreateLogGroup" to the IAM policy below.
resource "aws_cloudwatch_log_group" "lamda_cloudwatch_group" {
  name              = "/aws/lambda/${var.lambda_function_name}"
  retention_in_days = 14
}


resource "aws_lambda_function" "slack_notification" {
  function_name = var.lambda_function_name
  role          = aws_iam_role.lambda_role.arn
  image_uri     = var.ecr_image_uri
  package_type  = "Image"
  architectures = ["x86_64"]
  timeout       = 20
  environment {
    variables = var.env_vars
  }

  depends_on = [
    aws_cloudwatch_log_group.lamda_cloudwatch_group
  ]
}

every morning we get these messages for all our accounts / the lambda is deployed in all our accounts :
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant