Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
AyodeAwe committed Nov 25, 2024
1 parent 14172f1 commit 036ea01
Show file tree
Hide file tree
Showing 10 changed files with 371 additions and 0 deletions.
118 changes: 118 additions & 0 deletions .github/workflows/deploy-v2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: deploy-probot

on:
workflow_dispatch:
push:
branches:
- "pull-request/[0-9]+"
- "main"

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
id-token: write
contents: read

jobs:
deploy:
name: Deploy Probot Application
runs-on: ubuntu-latest

steps:
- name: Get AWS credentials
uses: aws-actions/configure-aws-credentials@v3
with:
role-to-assume: ${{ vars.role-to-assume }}
aws-region: ${{ vars.AWS_REGION }}

- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'

- name: Install npm dependencies
run: npm ci

- name: Test Probot
run: npm run test

- name: Build Probot
run: npm run build

- name: Set deployment version
if: github.ref == 'refs/heads/main'
run: |
echo "DEPLOY_VERSION=$(date +%Y%m%d-%H%M%S)-$(git rev-parse --short HEAD)" >> $GITHUB_ENV
- name: Package Lambda functions
run: |
cd dist
zip -r ../probot-${{ env.DEPLOY_VERSION }}.zip .
cd ..
zip -r authorizer-${{ env.DEPLOY_VERSION }}.zip dist/authorizer.js
- name: Copy release draft template
run: cp src/plugins/ReleaseDrafter/draft_template.njk dist/plugins/ReleaseDrafter

- name: Upload to S3
if: github.ref == 'refs/heads/main'
run: |
aws s3 cp probot-${{ env.DEPLOY_VERSION }}.zip s3://rapidsai-serverless-deployments/serverless/ops-bot/prod/
aws s3 cp authorizer-${{ env.DEPLOY_VERSION }}.zip s3://rapidsai-serverless-deployments/serverless/ops-bot/prod/
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.9.2"

- name: Terraform Format Check
working-directory: terraform
run: terraform fmt -check

- name: Terraform Init
working-directory: terraform
run: terraform init

- name: Terraform Validate
working-directory: terraform
run: terraform validate

- name: Terraform Plan
working-directory: terraform
run: terraform plan -out=tfplan -var="deployment_version=${{ env.DEPLOY_VERSION }}"
env:
TF_VAR_app_id: ${{ secrets.APP_ID }}
TF_VAR_webhook_secret: ${{ secrets.WEBHOOK_SECRET }}
TF_VAR_private_key: ${{ secrets.PRIVATE_KEY }}
TF_VAR_gputester_pat: ${{ secrets.GPUTESTER_PAT }}

- name: Update PR with Plan
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const output = `#### Terraform Plan 📝
\`\`\`\n
${process.env.PLAN}
\`\`\`
`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
- name: Terraform Plan Status
if: steps.plan.outcome == 'failure'
run: exit 1

- name: Terraform Apply
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
working-directory: terraform
run: terraform apply -auto-approve tfplan
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ npm-debug.log
coverage
dist
.serverless
*.tfvars
.terraform*
56 changes: 56 additions & 0 deletions terraform/api_gateway.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
resource "aws_api_gateway_rest_api" "ops_bot" {
name = "ops-bot-${var.environment}"
}

resource "aws_api_gateway_resource" "proxy" {
rest_api_id = aws_api_gateway_rest_api.ops_bot.id
parent_id = aws_api_gateway_rest_api.ops_bot.root_resource_id
path_part = "{proxy+}"
}

resource "aws_api_gateway_method" "proxy" {
rest_api_id = aws_api_gateway_rest_api.ops_bot.id
resource_id = aws_api_gateway_resource.proxy.id
http_method = "POST"
authorization = "CUSTOM"
authorizer_id = aws_api_gateway_authorizer.ops_bot.id
}

resource "aws_api_gateway_authorizer" "ops_bot" {
name = "ops-bot-authorizer"
rest_api_id = aws_api_gateway_rest_api.ops_bot.id
authorizer_uri = aws_lambda_function.authorizer.invoke_arn
authorizer_credentials = aws_iam_role.api_gateway_authorizer.arn
type = "REQUEST"
}

resource "aws_api_gateway_integration" "lambda" {
rest_api_id = aws_api_gateway_rest_api.ops_bot.id
resource_id = aws_api_gateway_resource.proxy.id
http_method = aws_api_gateway_method.proxy.http_method

integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.probot_handler.invoke_arn
}

resource "aws_api_gateway_deployment" "ops_bot" {
rest_api_id = aws_api_gateway_rest_api.ops_bot.id
triggers = {
redeployment = sha1(jsonencode([
aws_api_gateway_resource.proxy.id,
aws_api_gateway_method.proxy.id,
aws_api_gateway_integration.lambda.id,
]))
}

lifecycle {
create_before_destroy = true
}
}

resource "aws_api_gateway_stage" "ops_bot" {
deployment_id = aws_api_gateway_deployment.ops_bot.id
rest_api_id = aws_api_gateway_rest_api.ops_bot.id
stage_name = var.environment
}
9 changes: 9 additions & 0 deletions terraform/cloudwatch.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
resource "aws_cloudwatch_log_group" "probot_handler" {
name = "/aws/lambda/ops-bot-${var.environment}-handleProbot"
retention_in_days = 60
}

resource "aws_cloudwatch_log_group" "authorizer" {
name = "/aws/lambda/ops-bot-${var.environment}-authorizerFn"
retention_in_days = 60
}
71 changes: 71 additions & 0 deletions terraform/iam.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
resource "aws_iam_role" "lambda_role" {
name = "ops-bot-${var.environment}-lambda-role"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = ["sts:AssumeRole"]
Effect = "Allow"
Principal = {
Service = ["lambda.amazonaws.com"]
}
}]
})
}

resource "aws_iam_role_policy" "lambda_policy" {
name = "ops-bot-${var.environment}-lambda-policy"
role = aws_iam_role.lambda_role.id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = ["lambda:InvokeFunction"]
Resource = [
aws_lambda_function.probot_handler.arn
# aws_lambda_function.authorizer.arn
]
},
{
Effect = "Allow"
Action = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
Resource = ["arn:aws:logs:*:*:*"]
}
]
})
}

resource "aws_iam_role" "api_gateway_authorizer" {
name = "ops-bot-${var.environment}-api-gateway-authorizer"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = ["sts:AssumeRole"]
Effect = "Allow"
Principal = {
Service = ["apigateway.amazonaws.com"]
}
}]
})
}

resource "aws_iam_role_policy" "api_gateway_authorizer" {
name = "ops-bot-${var.environment}-api-gateway-authorizer"
role = aws_iam_role.api_gateway_authorizer.id

policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["lambda:InvokeFunction"]
Resource = [aws_lambda_function.authorizer.arn]
}]
})
}
50 changes: 50 additions & 0 deletions terraform/lambda.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
resource "aws_lambda_function" "probot_handler" {
depends_on = [aws_cloudwatch_log_group.probot_handler]
s3_bucket = data.aws_s3_bucket.deployment.id
s3_key = "probot-${var.deployment_version}.zip"
function_name = "ops-bot-${var.environment}-handleProbot"
role = aws_iam_role.lambda_role.arn
handler = "dist/probot.handler"
runtime = "nodejs18.x"
timeout = 900
memory_size = 1024

environment {
variables = {
NODE_ENV = var.environment
LOG_FORMAT = "json"
LOG_LEVEL = "debug"
APP_ID = var.app_id
WEBHOOK_SECRET = var.webhook_secret
PRIVATE_KEY = var.private_key
GPUTESTER_PAT = var.gputester_pat
}
}

lifecycle {
create_before_destroy = true
prevent_destroy = true
}
}

resource "aws_lambda_function" "authorizer" {
depends_on = [aws_cloudwatch_log_group.authorizer]
s3_bucket = data.aws_s3_bucket.deployment.id
s3_key = "authorizer-${var.deployment_version}.zip"
function_name = "ops-bot-${var.environment}-authorizerFn"
role = aws_iam_role.lambda_role.arn
handler = "dist/authorizer.handler"
runtime = "nodejs18.x"
memory_size = 1024

environment {
variables = {
probotFnName = aws_lambda_function.probot_handler.function_name
}
}

lifecycle {
create_before_destroy = true
prevent_destroy = true
}
}
18 changes: 18 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}

backend "s3" {
bucket = "rapidsai-tf-state"
key = "ops-bot/terraform.tfstate"
region = "us-east-2"
}
}

provider "aws" {
region = "us-east-2"
}
4 changes: 4 additions & 0 deletions terraform/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "api_gateway_url" {
description = "Base URL for API Gateway stage"
value = "${aws_api_gateway_stage.ops_bot.invoke_url}/"
}
3 changes: 3 additions & 0 deletions terraform/s3.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
data "aws_s3_bucket" "deployment" {
bucket = "rapidsai-serverless-deployments"
}
40 changes: 40 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
variable "aws_region" {
description = "AWS region"
type = string
default = "us-east-2"
}

variable "environment" {
description = "Environment name"
type = string
default = "dev"
}

variable "app_id" {
description = "GitHub App ID"
type = string
sensitive = true
}

variable "webhook_secret" {
description = "GitHub Webhook Secret"
type = string
sensitive = true
}

variable "private_key" {
description = "GitHub App Private Key"
type = string
sensitive = true
}

variable "gputester_pat" {
description = "GPU Tester PAT"
type = string
sensitive = true
}

variable "deployment_version" {
description = "Version identifier for Lambda deployment packages"
type = string
}

0 comments on commit 036ea01

Please sign in to comment.