From 5cbce3a74a4ef105a725dc4db86402a096d9de10 Mon Sep 17 00:00:00 2001 From: arnol377 Date: Mon, 21 Apr 2025 14:15:13 -0400 Subject: [PATCH] Add GitHub Actions workflow and infrastructure for building Lambda container --- .github/workflows/build-lambda.yml | 49 +++++++++ buildspec.yml | 25 +++++ .../github-actions-trust-policy.json | 20 ++++ infrastructure/main.tf | 99 +++++++++++++++++++ infrastructure/outputs.tf | 14 +++ infrastructure/providers.tf | 12 +++ infrastructure/variables.tf | 15 +++ 7 files changed, 234 insertions(+) create mode 100644 .github/workflows/build-lambda.yml create mode 100644 buildspec.yml create mode 100644 infrastructure/github-actions-trust-policy.json create mode 100644 infrastructure/main.tf create mode 100644 infrastructure/outputs.tf create mode 100644 infrastructure/providers.tf create mode 100644 infrastructure/variables.tf diff --git a/.github/workflows/build-lambda.yml b/.github/workflows/build-lambda.yml new file mode 100644 index 0000000..591309a --- /dev/null +++ b/.github/workflows/build-lambda.yml @@ -0,0 +1,49 @@ +name: Build Lambda Container + +on: + push: + branches: + - main + - master + pull_request: + branches: + - main + - master + workflow_dispatch: + +permissions: + id-token: write + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN }} + aws-region: ${{ vars.AWS_REGION }} + + - name: Start CodeBuild Project + run: | + BUILD_ID=$(aws codebuild start-build --project-name eks-automation-lambda-builder --output text --query 'build.id') + echo "Started build with ID: $BUILD_ID" + + while true; do + STATUS=$(aws codebuild batch-get-builds --ids $BUILD_ID --query 'builds[0].buildStatus' --output text) + echo "Build status: $STATUS" + + if [ "$STATUS" = "SUCCEEDED" ]; then + echo "Build completed successfully!" + exit 0 + elif [ "$STATUS" = "FAILED" ] || [ "$STATUS" = "STOPPED" ] || [ "$STATUS" = "TIMED_OUT" ]; then + echo "Build failed with status: $STATUS" + exit 1 + fi + + sleep 30 + done diff --git a/buildspec.yml b/buildspec.yml new file mode 100644 index 0000000..e0ddb58 --- /dev/null +++ b/buildspec.yml @@ -0,0 +1,25 @@ +version: 0.2 + +phases: + install: + runtime-versions: + python: 3.11 + commands: + - curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - + - sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" + - sudo apt-get update && sudo apt-get install packer + + pre_build: + commands: + - echo "Initializing Packer plugins..." + - packer init . + - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $REPOSITORY_URI + + build: + commands: + - echo "Building the Lambda container image with Packer..." + - packer build -var="repository_uri=$REPOSITORY_URI" packer.pkr.hcl + + post_build: + commands: + - echo "Build completed successfully!" diff --git a/infrastructure/github-actions-trust-policy.json b/infrastructure/github-actions-trust-policy.json new file mode 100644 index 0000000..684318a --- /dev/null +++ b/infrastructure/github-actions-trust-policy.json @@ -0,0 +1,20 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/token.actions.githubusercontent.com" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringLike": { + "token.actions.githubusercontent.com:sub": "repo:${YOUR_GITHUB_ORG}/${YOUR_REPO_NAME}:*" + }, + "StringEquals": { + "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" + } + } + } + ] +} diff --git a/infrastructure/main.tf b/infrastructure/main.tf new file mode 100644 index 0000000..39b850a --- /dev/null +++ b/infrastructure/main.tf @@ -0,0 +1,99 @@ +# IAM Role for CodeBuild +resource "aws_iam_role" "codebuild" { + name = "eks-automation-lambda-codebuild-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = "codebuild.amazonaws.com" + } + } + ] + }) +} + +# IAM Role Policy for CodeBuild +resource "aws_iam_role_policy" "codebuild" { + name = "eks-automation-lambda-codebuild-policy" + role = aws_iam_role.codebuild.id + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Resource = ["*"] + Action = [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ] + }, + { + Effect = "Allow" + Resource = ["*"] + Action = [ + "ecr:GetAuthorizationToken", + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:BatchGetImage", + "ecr:PutImage", + "ecr:InitiateLayerUpload", + "ecr:UploadLayerPart", + "ecr:CompleteLayerUpload", + "codebuild:StartBuild", + "codebuild:BatchGetBuilds", + "codebuild:StopBuild" + ] + }, + "ecr:CompleteLayerUpload" + ] + } + ] + }) +} + +# CodeBuild Project +resource "aws_codebuild_project" "lambda_builder" { + name = "eks-automation-lambda-builder" + service_role = aws_iam_role.codebuild.arn + build_timeout = "30" + + artifacts { + type = "NO_ARTIFACTS" + } + + environment { + compute_type = "BUILD_GENERAL1_SMALL" + image = "aws/codebuild/amazonlinux2-x86_64-standard:4.0" + type = "LINUX_CONTAINER" + image_pull_credentials_type = "CODEBUILD" + privileged_mode = true + + environment_variable { + name = "REPOSITORY_URI" + value = var.repository_uri + } + } + + source { + type = "GITHUB" + location = var.github_repo_url + git_clone_depth = 1 + buildspec = "buildspec.yml" + } + + cache { + type = "NO_CACHE" + } + + logs_config { + cloudwatch_logs { + status = "ENABLED" + } + } +} diff --git a/infrastructure/outputs.tf b/infrastructure/outputs.tf new file mode 100644 index 0000000..9d417b0 --- /dev/null +++ b/infrastructure/outputs.tf @@ -0,0 +1,14 @@ +output "codebuild_project_name" { + description = "Name of the CodeBuild project" + value = aws_codebuild_project.lambda_builder.name +} + +output "codebuild_project_arn" { + description = "ARN of the CodeBuild project" + value = aws_codebuild_project.lambda_builder.arn +} + +output "iam_role_arn" { + description = "ARN of the IAM role used by CodeBuild" + value = aws_iam_role.codebuild.arn +} diff --git a/infrastructure/providers.tf b/infrastructure/providers.tf new file mode 100644 index 0000000..3a69900 --- /dev/null +++ b/infrastructure/providers.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + +provider "aws" { + region = var.aws_region +} diff --git a/infrastructure/variables.tf b/infrastructure/variables.tf new file mode 100644 index 0000000..ad68078 --- /dev/null +++ b/infrastructure/variables.tf @@ -0,0 +1,15 @@ +variable "aws_region" { + description = "AWS region where resources will be created" + type = string + default = "us-west-2" +} + +variable "repository_uri" { + description = "The URI of the ECR repository where the Lambda image will be pushed" + type = string +} + +variable "github_repo_url" { + description = "The HTTPS clone URL of the GitHub repository" + type = string +}