Skip to content

Commit

Permalink
Merge pull request #1 from SCT-Engineering/teraform-deployment
Browse files Browse the repository at this point in the history
updating terraform based deployment
  • Loading branch information
arnol377 committed Apr 15, 2025
2 parents b7116d2 + 972d53f commit 4b45901
Show file tree
Hide file tree
Showing 17 changed files with 405 additions and 124 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/gh-token.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: GitHub Token Refresh

on:
schedule:
- cron: '*/5 * * * *' # Runs every 5 minutes
workflow_dispatch: # Allows manual triggering

jobs:
refresh-token:
name: Refresh GitHub Token
uses: CSVD/centralized-actions/.github/workflows/upload-github-token.yml@main
with:
aws_region: 'us-east-1'
secret_name: '/dev/eks_automation_github_token' # This matches the SECRET_NAME in app.py
github_app_id: ${{ vars.GITHUB_APP_ID }}
github_installation_id: ${{ vars.GITHUB_INSTALLATION_ID }}
use_ecs_credentials: true
secrets:
github_app_private_key: ${{ secrets.GITHUB_APP_PRIVATE_KEY }}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,6 @@ cython_debug/
artifacts/

.aws-sam

terraform_data_dirs
terraform.tfstate.d
42 changes: 42 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.PHONY: init venv install-deps clean terraform-init terraform-plan terraform-apply package all

PYTHON=python3
PIP=pip3
TERRAFORM=terraform
VENV=.venv
VENV_BIN=$(VENV)/bin
VENV_PIP=$(VENV_BIN)/pip

# Set PIP_CONFIG_FILE to use custom pip.conf
export PIP_CONFIG_FILE=$(CURDIR)/scripts/pip.conf

all: venv install-deps package terraform-apply

venv:
test -d $(VENV) || $(PYTHON) -m venv $(VENV)
$(VENV_PIP) install --upgrade pip setuptools wheel

install-deps: venv
source $(VENV_BIN)/activate && $(VENV_PIP) install -r scripts/requirements.txt

clean:
rm -rf dist/
rm -f *.zip
rm -rf __pycache__/
rm -rf .terraform/
rm -rf $(VENV)

package: venv
source $(VENV_BIN)/activate && chmod +x scripts/package.sh && ./scripts/package.sh

terraform-init:
$(TERRAFORM) init

terraform-plan: terraform-init
$(TERRAFORM) plan

terraform-apply: terraform-init package
$(TERRAFORM) apply -auto-approve

terraform-destroy:
$(TERRAFORM) destroy -auto-approve
Empty file added backend.tf
Empty file.
227 changes: 227 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
provider "aws" {
default_tags = {
organization = "census:ocio:csvd"
finops_project_name = "csvd_platformbaseline"
finops_project_number = "fs0000000078"
finops_project_role = "csvd_platformbaseline_app"
}
}

locals {
common_tags = {
environment = var.environment
environment_abbr = var.environment_abbr
organization = var.organization
finops_project_name = var.finops_project_name
finops_project_number = var.finops_project_number
finops_project_role = var.finops_project_role
}
}

# API Gateway
resource "aws_api_gateway_rest_api" "eks_automation" {
name = "eks-automation-api"
tags = local.common_tags
}

resource "aws_api_gateway_resource" "eks_automation" {
rest_api_id = aws_api_gateway_rest_api.eks_automation.id
parent_id = aws_api_gateway_rest_api.eks_automation.root_resource_id
path_part = "EKSAutomation"
}

resource "aws_api_gateway_method" "eks_automation" {
rest_api_id = aws_api_gateway_rest_api.eks_automation.id
resource_id = aws_api_gateway_resource.eks_automation.id
http_method = "POST"
authorization = "NONE"
api_key_required = true
}

resource "aws_api_gateway_integration" "lambda" {
rest_api_id = aws_api_gateway_rest_api.eks_automation.id
resource_id = aws_api_gateway_resource.eks_automation.id
http_method = aws_api_gateway_method.eks_automation.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.eks_automation.invoke_arn
}

resource "aws_api_gateway_deployment" "eks_automation" {
rest_api_id = aws_api_gateway_rest_api.eks_automation.id
depends_on = [aws_api_gateway_integration.lambda]
}

resource "aws_api_gateway_stage" "prod" {
deployment_id = aws_api_gateway_deployment.eks_automation.id
rest_api_id = aws_api_gateway_rest_api.eks_automation.id
stage_name = "Prod"
}

resource "aws_lambda_permission" "apigw" {
statement_id = "AllowAPIGatewayInvoke"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.eks_automation.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${aws_api_gateway_rest_api.eks_automation.execution_arn}/*/*"
}

resource "aws_api_gateway_method" "options" {
rest_api_id = aws_api_gateway_rest_api.eks_automation.id
resource_id = aws_api_gateway_resource.eks_automation.id
http_method = "OPTIONS"
authorization = "NONE"
}

resource "aws_api_gateway_integration" "options" {
rest_api_id = aws_api_gateway_rest_api.eks_automation.id
resource_id = aws_api_gateway_resource.eks_automation.id
http_method = aws_api_gateway_method.options.http_method
type = "MOCK"
request_templates = {
"application/json" = "{\"statusCode\": 200}"
}
}

resource "aws_api_gateway_method_response" "options" {
rest_api_id = aws_api_gateway_rest_api.eks_automation.id
resource_id = aws_api_gateway_resource.eks_automation.id
http_method = aws_api_gateway_method.options.http_method
status_code = "200"

response_parameters = {
"method.response.header.Access-Control-Allow-Headers" = true,
"method.response.header.Access-Control-Allow-Methods" = true,
"method.response.header.Access-Control-Allow-Origin" = true
}
}

resource "aws_api_gateway_integration_response" "options" {
rest_api_id = aws_api_gateway_rest_api.eks_automation.id
resource_id = aws_api_gateway_resource.eks_automation.id
http_method = aws_api_gateway_method.options.http_method
status_code = aws_api_gateway_method_response.options.status_code

response_parameters = {
"method.response.header.Access-Control-Allow-Headers" = "'Content-Type,Authorization'",
"method.response.header.Access-Control-Allow-Methods" = "'POST,OPTIONS'",
"method.response.header.Access-Control-Allow-Origin" = "'*'"
}
}

resource "aws_api_gateway_usage_plan" "eks_automation" {
name = "eks-automation-usage-plan"
description = "Usage plan for EKS Automation API"

api_stages {
api_id = aws_api_gateway_rest_api.eks_automation.id
stage = aws_api_gateway_stage.prod.stage_name
}

quota_settings {
limit = 5000
period = "MONTH"
}

throttle_settings {
burst_limit = 500
rate_limit = 100
}

tags = local.common_tags
}

resource "aws_api_gateway_api_key" "eks_automation" {
name = "eks-automation-api-key"
}

resource "aws_api_gateway_usage_plan_key" "eks_automation" {
key_id = aws_api_gateway_api_key.eks_automation.id
key_type = "API_KEY"
usage_plan_id = aws_api_gateway_usage_plan.eks_automation.id
}

# Lambda Layer
resource "aws_lambda_layer_version" "git" {
filename = "layer.zip" # Make sure to create this zip file with Git binaries
layer_name = "git-lambda-layer"
description = "Git Lambda Layer"
compatible_runtimes = ["python3.9", "python3.10", "python3.11"]
}

# Lambda Function
resource "aws_lambda_function" "eks_automation" {
filename = "eks_automation.zip" # Make sure to create this zip file
function_name = "eks-automation"
role = aws_iam_role.lambda_role.arn
handler = "app.lambda_handler"
runtime = "python3.11"
timeout = var.lambda_timeout

vpc_config {
subnet_ids = var.vpc_subnet_ids
security_group_ids = var.vpc_security_group_ids
}

layers = [aws_lambda_layer_version.git.arn]

environment {
variables = {
ENVIRONMENT = var.environment
}
}

tags = local.common_tags
}

# IAM Role for Lambda
resource "aws_iam_role" "lambda_role" {
name = "eks-automation-lambda-role"

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

tags = local.common_tags
}

# IAM Policies
resource "aws_iam_role_policy_attachment" "lambda_vpc_access" {
role = aws_iam_role.lambda_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
}

resource "aws_iam_role_policy" "lambda_ssm_access" {
name = "eks-automation-ssm-access"
role = aws_iam_role.lambda_role.id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "SSMDescribeParametersPolicy"
Effect = "Allow"
Action = ["ssm:DescribeParameters"]
Resource = "*"
},
{
Sid = "SSMGetParameterPolicy"
Effect = "Allow"
Action = [
"ssm:GetParameters",
"ssm:GetParameter"
]
Resource = "*"
}
]
})
}
10 changes: 10 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
output "api_endpoint" {
description = "API Gateway endpoint URL"
value = "${aws_api_gateway_stage.prod.invoke_url}${aws_api_gateway_resource.eks_automation.path}"
}

output "api_key" {
description = "API Key for accessing the endpoint"
value = aws_api_gateway_api_key.eks_automation.value
sensitive = true
}
9 changes: 0 additions & 9 deletions samconfig.toml

This file was deleted.

24 changes: 24 additions & 0 deletions scripts/package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash

# Create temporary directories
mkdir -p dist/lambda
mkdir -p dist/layer

# Package Lambda function
cp -r eks_automation/* dist/lambda/
cd dist/lambda
zip -r ../eks_automation.zip .
cd ../..

# Package Lambda layer
mkdir -p dist/layer/python
pip install -r eks_automation/requirements.txt -t dist/layer/python
cd dist/layer
zip -r ../layer.zip .
cd ../..

# Move zip files to root
mv dist/*.zip .

# Cleanup
rm -rf dist
10 changes: 10 additions & 0 deletions scripts/pip.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[global]
cert = /etc/pki/ca-trust/source/anchors/katello-server-ca.pem
#proxy = http://proxy.tco.census.gov:3128
index = https://nexus.it.census.gov:8443/repository/DataScience-Group/pypi
index-url = https://nexus.it.census.gov:8443/repository/DataScience-Group/simple
trusted-host = nexus.it.census.gov
pypi.python.org
pypi.org
files.pythonhosted.org
proxy.tco.census.gov
5 changes: 5 additions & 0 deletions scripts/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Jinja2>=3.1.0
PyGithub>=2.1.1
GitPython>=3.1.40
boto3>=1.34.0
botocore>=1.34.0
Loading

0 comments on commit 4b45901

Please sign in to comment.