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

added github action with terraform deploy #4

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .github/workflows/deploy-to-azure.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Deploy to Azure

on:
push:
branches: ["main", "terraform-deploy"] # Trigger on pushes to the 'main' branch
pull_request:
branches: ["main"]

jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3

# Log in to Azure Container Registry (ACR)
- name: Log in to Azure Container Registry
uses: azure/docker-login@v1
with:
login-server: ${{ secrets.ACR_SERVER }}
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}

# Build Docker image
- name: Build Docker image
run: |
docker build -f CubeLogic.TransactionsConverter/Dockerfile -t ${{ secrets.ACR_SERVER }}/transconv:latest .

# Run Snyk security scan
# - name: Run Snyk Security Scan
# uses: snyk/actions/docker@v2
# with:
# image: ${{ secrets.ACR_SERVER }}/transconv:latest
# args: --severity-threshold=high
# env:
# SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

# Push Docker image to ACR
- name: Push Docker image
run: |
docker push ${{ secrets.ACR_SERVER }}/transconv:latest

- name: Setup Terraform
uses: hashicorp/setup-terraform@v2

- name: Login to Azure
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Change working directory
run: |
cd deploy

- name: Initialize Terraform
run: |
terraform init -backend-config="config=/dev/null"

- name: Plan
run: |
terraform plan -out=plan

- name: Apply
run: |
terraform apply -auto-approve plan

- name: Output
run: |
terraform output -json > outputs.json
30 changes: 25 additions & 5 deletions CubeLogic.TransactionsConverter/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,42 @@

# Set the working directory inside the container
WORKDIR /app
COPY ["CubeLogic.TransactionsConverter.csproj", "./"]
COPY ["CubeLogic.TransactionsConverter/CubeLogic.TransactionsConverter.csproj", "./"]
RUN dotnet restore

# Copy the entire project directory and build the application
COPY . ./
COPY CubeLogic.TransactionsConverter/ ./
RUN dotnet publish -c Release -o /out /p:UseAppHost=false

FROM mcr.microsoft.com/dotnet/runtime:8.0

# Set the working directory for the runtime container
WORKDIR /app

# Create a non-root user
RUN useradd -m -u 1000 appuser

# Switch to the new user
USER appuser

# Create empty volumes for each argument path
VOLUME ["--mode=0755", "/app/input_file_path"]
VOLUME ["--mode=0755", "/app/config_file_path"]
VOLUME ["--mode=0755", "/app/output"]


# Copy the built application from the build stage
COPY --from=build-env /out ./
COPY InputTransactions.csv ./
COPY config.json ./

# Pass arguments as environment variables
ENV INPUT_PATH=/app/InputTransactions.csv
ENV CONFIG_PATH=/app/config.json
ENV OUTPUT_PATH=/app/output/output.csv

USER $APP_UID
ENTRYPOINT ["dotnet", "CubeLogic.TransactionsConverter.dll"]
ENTRYPOINT ["sh", "-c", "dotnet CubeLogic.TransactionsConverter.dll --input ${INPUT_PATH} --config ${CONFIG_PATH} --output ${OUTPUT_PATH}"]

# Example how to run
# folder with input files is called input_file_path
# folder for output file is called output
# docker run -u root -v $(pwd)/input_file_path/inputTransactions.csv:/app/inputTransactions.csv -v $(pwd)/input_file_path/config.json:/app/input_file_path/config.json -v $(pwd)/output:/app/output transconv
181 changes: 181 additions & 0 deletions deploy/azure.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "4.14.0"
}
}
}

provider "azurerm" {
features {}


}

# Resource group
resource "azurerm_resource_group" "rg" {
name = "dotnet-app-rg"
location = "UK South"
}

# Storage account for input and output files
resource "azurerm_storage_account" "storage" {
name = "dotnetappstorage"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
account_replication_type = "LRS"
}

# Storage container for input files
resource "azurerm_storage_container" "input_files" {
name = "inputfiles"
storage_account_name = azurerm_storage_account.storage.name
container_access_type = "private"
}

# Storage container for output files
resource "azurerm_storage_container" "output_files" {
name = "outputfiles"
storage_account_name = azurerm_storage_account.storage.name
container_access_type = "blob"
}


# Event Grid Topic for input file changes
resource "azurerm_eventgrid_topic" "input_file_changes" {
name = "input-file-changes-topic"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}

# Event Subscription for WebJob
resource "azurerm_eventgrid_event_subscription" "webjob_subscription" {
name = "webjob-subscription"
scope = azurerm_eventgrid_topic.input_file_changes.id

webhook_endpoint {
url = "http://${azurerm_container_group.container.ip_address}"
}

included_event_types = ["Microsoft.Storage.BlobCreated", "Microsoft.Storage.BlobDeleted"]

retry_policy {
max_delivery_attempts = 3
event_time_to_live = 1440
}
}

# Event Subscription for Logic App
resource "azurerm_eventgrid_event_subscription" "logicapp_subscription" {
name = "logicapp-subscription"
scope = azurerm_eventgrid_topic.input_file_changes.id

webhook_endpoint {
url = azurerm_logic_app_workflow.file_change_email.access_endpoint
}
included_event_types = ["Microsoft.Storage.BlobCreated", "Microsoft.Storage.BlobDeleted"]

retry_policy {
max_delivery_attempts = 3
event_time_to_live = 1440
}
}

# Azure Container Instance for the WebJob application
resource "azurerm_container_group" "container" {
name = "dotnet-webjob-container"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
os_type = "Linux"

container {
name = "dotnet-webjob"
image = "your-webjob-docker-image:latest"
cpu = "0.5"
memory = "1.5"

environment_variables = {
AzureWebJobsStorage = azurerm_storage_account.storage.primary_connection_string
}

volume {
name = "input-volume"
mount_path = "/mnt/input"

share_name = azurerm_storage_container.input_files.name
storage_account_name = azurerm_storage_account.storage.name
storage_account_key = azurerm_storage_account.storage.primary_access_key

}

volume {
name = "output-volume"
mount_path = "/mnt/output"
share_name = azurerm_storage_container.output_files.name
storage_account_name = azurerm_storage_account.storage.name
storage_account_key = azurerm_storage_account.storage.primary_access_key

}

}

restart_policy = "OnFailure"
}

# Logic App to send emails on input file changes
resource "azurerm_logic_app_workflow" "file_change_email" {
name = "file-change-email-logic-app"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name

workflow_schema = jsonencode({
"$schema" = "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowDefinition.json#"
"actions" = {
"Send_an_email" = {
"inputs" = {
"body" = "File change detected in the input files."
"subject" = "File Change Notification"
"to" = "dynamic-email-list@from-config"
"host" = {
"connectionName" = "office365"
"operationId" = "SendEmail"
"connection" = {
"name" = "@parameters('$connections')['office365']['connectionId']"
}
}
}
"runAfter" = {}
"type" = "ApiConnection"
}
}
"triggers" = {
"When_a_blob_is_added_or_modified" = {
"inputs" = {
"parameters" = {
"blobPath" = "inputfiles/*"
"connection" = {
"name" = "@parameters('$connections')['azureblob']['connectionId']"
}
}
"recurrence" = {
"frequency" = "Minute"
"interval" = 5
}
}
"metadata" = {
"operationId" = "OnUpdatedFile"
"connectionName" = "azureblob"
}
"type" = "ApiConnection"
}
}
})
}


# Output for container public IP
output "container_ip" {
value = azurerm_container_group.container.ip_address
}
Loading