Skip to content

PR - DataRisk Challenge #7

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

Open
wants to merge 10 commits into
base: master
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
37 changes: 37 additions & 0 deletions .github/workflows/kubernetes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: CI/CD Pipeline

on:
push:
branches:
- master

jobs:
build:
name: Build and Push Docker Image
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Login to GitHub Container Registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin

- name: Build and Push Docker Image
run: |
docker build -t ghcr.io/${{ github.repository_owner }}/fsharp-app:latest -f projeto-fsharp/Dockerfile .
docker push ghcr.io/${{ github.repository_owner }}/fsharp-app:latest

deploy:
name: Deploy to Kubernetes
runs-on: ubuntu-latest
needs: build

steps:
- name: Set up Kubernetes
uses: azure/setup-kubectl@v3
with:
version: 'v1.21.0'
36 changes: 36 additions & 0 deletions .github/workflows/terra.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Terraform Plan

on:
pull_request:
paths:
- 'infraservices/terras/**'

jobs:
plan:
name: 'Terraform Plan'
runs-on: ubuntu-latest

env:
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}

steps:
- name: Checkout Repository
uses: actions/checkout@v3

- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.5.0 # Atualize para a versão desejada

- name: Terraform Init
run: terraform init
working-directory: infraservices/terras

- name: Terraform Plan
run: terraform plan
working-directory: infraservices/terras
env:
DEBUG: true
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.gitignore
.fable/
.idea/
.ionide/
Expand All @@ -22,10 +23,15 @@ docs-build/
build/
__pycache__


# Extra
*errors.txt
*logs.txt
*~
\#*\#
.\#*
logs/

#For me
infraservices/terras/.terraform*
infraservices/terras/variable.tf
30 changes: 30 additions & 0 deletions README-InitChallenge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Datapi DevOps Challenge

Para melhor entendermos o seu nível técnico, nós preparamos este desafio como parte do nosso processo de contratação. Por isso, tenha em mente que não é necessário cumprir com todos os pontos mencionados, nem cumpri-los em uma ordem específica.

O importante é entregar o que você conseguir fazer, com a devida documentação.

# Desafios

Segue abaixo uma lista de desafios abrangendo várias áreas de responsabilidade para um DevOps no time do Datapi. Nossa sugestão é tentar seguir cada item na ordem apresentada, porém você está livre para atuar nos pontos que quiser e tiver mais familiaridade.

- Instanciar uma VM numa cloud provider. Recomendação: Microsoft Azure.
- Criar a configuração dessa VM usando uma ferramenta de IaC (Infrastructure as Code). Recomendação: Terraform.
- Criar um job de CI (Continuous Integration) para aplicar a configuração da ferramenta de provisionamento. Recomendação: GitHub Actions.
- Adicionar um Dockerfile à aplicação disponibilizada na pasta `projeto-fsharp/` para containerizar o mesmo. Note que foi utilizada a linguagem F# (.NET) para escrever a aplicação. Para facilitar o entendimento do projeto, adicionamos um README.md com instruções de teste e uso do mesmo localmente. Você deverá ser capaz de traduzir essas instruções para a criação do Dockerfile.
- Criar um job de CI para enviar a imagem gerada para um Docker Registry. Recomendação: GitHub Container Registry.
- Criar os manifestos YAML para hospedar a aplicação usando Kubernetes. Nesse ponto os testes podem ser realizados apenas localmente, porém devem ser apresentados os arquivos YAML criados.
* Utilizar IaC para configurar o Kubernetes. Recomendação: Terraform.
* Configurar a hospedagem a partir do registry gerado na tarefa anterior.
* Caso possua mais familiaridade, sinta-se motivado a customizar mais as configurações (secrets, ingress, etc.).
- Adicionar um README ao projeto detalhando o processo e justificando as decisões tomadas. Recomendação: Markdown. Todos os refinamentos adicionados nos tópicos mencionados anteriormente, e demais ideias que possam melhorar o projeto serão considerados na avaliação da solução.

Faça um fork e envie um PR com a sua solução, o tempo de entrega é de no máximo 4 dias e será contabilizado a partir da data do fork.

## Será avaliado:

- % do que foi entregue em relação ao que foi pedido.
- Qualidade dos aquivos Terraform.
- Boas práticas de infra e uso do Kubernetes.
- Corretude das tarefas.
- Uso eficiente em relação ao custo de máquina.
122 changes: 100 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,108 @@
# Datapi DevOps Challenge
## Documentação do Projeto Datapi DevOps Challenge

Para melhor entendermos o seu nível técnico, nós preparamos este desafio como parte do nosso processo de contratação. Por isso, tenha em mente que não é necessário cumprir com todos os pontos mencionados, nem cumpri-los em uma ordem específica.
### 1. Estrutura do Projeto

O importante é entregar o que você conseguir fazer, com a devida documentação.
#### **Diretório `infraservices`**

# Desafios
- **`terras/`**:
- Contém arquivos de configuração do Terraform para provisionamento da infraestrutura na Azure.

Segue abaixo uma lista de desafios abrangendo várias áreas de responsabilidade para um DevOps no time do Datapi. Nossa sugestão é tentar seguir cada item na ordem apresentada, porém você está livre para atuar nos pontos que quiser e tiver mais familiaridade.
**Arquivos:**
- `main.tf`:
- Define os recursos principais na Azure, incluindo Resource Group, Virtual Network, Subnet, Network Interface, Virtual Machine e Public IP.
- `output.tf`:
- Define as saídas do Terraform, que fornecem informações sobre o estado dos recursos criados.
- `provider.tf`:
- Configura o provedor Azure com as credenciais e recursos necessários.
- `variable.tf`:
- Define variáveis usadas para parametrizar a configuração da infraestrutura.

- Instanciar uma VM numa cloud provider. Recomendação: Microsoft Azure.
- Criar a configuração dessa VM usando uma ferramenta de IaC (Infrastructure as Code). Recomendação: Terraform.
- Criar um job de CI (Continuous Integration) para aplicar a configuração da ferramenta de provisionamento. Recomendação: GitHub Actions.
- Adicionar um Dockerfile à aplicação disponibilizada na pasta `projeto-fsharp/` para containerizar o mesmo. Note que foi utilizada a linguagem F# (.NET) para escrever a aplicação. Para facilitar o entendimento do projeto, adicionamos um README.md com instruções de teste e uso do mesmo localmente. Você deverá ser capaz de traduzir essas instruções para a criação do Dockerfile.
- Criar um job de CI para enviar a imagem gerada para um Docker Registry. Recomendação: GitHub Container Registry.
- Criar os manifestos YAML para hospedar a aplicação usando Kubernetes. Nesse ponto os testes podem ser realizados apenas localmente, porém devem ser apresentados os arquivos YAML criados.
* Utilizar IaC para configurar o Kubernetes. Recomendação: Terraform.
* Configurar a hospedagem a partir do registry gerado na tarefa anterior.
* Caso possua mais familiaridade, sinta-se motivado a customizar mais as configurações (secrets, ingress, etc.).
- Adicionar um README ao projeto detalhando o processo e justificando as decisões tomadas. Recomendação: Markdown. Todos os refinamentos adicionados nos tópicos mencionados anteriormente, e demais ideias que possam melhorar o projeto serão considerados na avaliação da solução.
- **`k8s/`**:
- Contém arquivos de configuração para Kubernetes.

Faça um fork e envie um PR com a sua solução, o tempo de entrega é de no máximo 4 dias e será contabilizado a partir da data do fork.
**Arquivos:**
- `deploy.yml`:
- Define o Deployment e o Service para a aplicação F# no Kubernetes.
- **Deployment**:
- Configura o Deployment da aplicação F#, incluindo o número de réplicas, a imagem Docker e os recursos solicitados (CPU e memória).
- **Service**:
- Define o Service Kubernetes para expor a aplicação F# externamente, utilizando um LoadBalancer.

## Será avaliado:
- **`token/`**:
- Contém arquivos de chave e autenticação para a infraestrutura.

- % do que foi entregue em relação ao que foi pedido.
- Qualidade dos aquivos Terraform.
- Boas práticas de infra e uso do Kubernetes.
- Corretude das tarefas.
- Uso eficiente em relação ao custo de máquina.
**Arquivos:**
- `id_rsa.pub`:
- Chave pública SSH para autenticação na máquina virtual provisionada.

#### **Diretório `projeto-fsharp`**

- **Contém o código da aplicação F# e o Dockerfile para criar a imagem Docker da aplicação.**

**Arquivos:**
- `Dockerfile`:
- Define as etapas para construir a imagem Docker da aplicação F#, incluindo a configuração do ambiente de execução e a cópia dos arquivos de build.
- `build.fsx`:
- Script de build da aplicação F#.
- `restore.sh`:
- Script para restaurar as dependências da aplicação.
- `README.md`:
- Documento explicativo sobre o projeto F# e instruções de uso.

---

### 2. Documentação dos Arquivos e Funcionalidades

#### **Terraform**

- **`main.tf`**:
- **Resource Group**:
- Cria um grupo de recursos na Azure.
- **Virtual Network**:
- Cria uma rede virtual com um espaço de endereços específico.
- **Subnet**:
- Cria uma sub-rede dentro da rede virtual.
- **Network Interface**:
- Cria uma interface de rede para a máquina virtual.
- **Linux Virtual Machine**:
- Provisiona uma máquina virtual Linux com configuração de rede e autenticação SSH.
- **Public IP**:
- Cria um IP público para acesso externo à máquina virtual.

- **`output.tf`**:
- **resource_group_name**: Nome do grupo de recursos.
- **virtual_network_name**: Nome da rede virtual.
- **subnet_id**: ID da sub-rede.
- **vm_public_ip**: Endereço IP público da máquina virtual.

- **`provider.tf`**:
- Configuração do provedor Azure com as credenciais e configuração necessárias para o Terraform.

- **`variable.tf`**:
- Define variáveis usadas em `main.tf`, como nome do grupo de recursos, localização e IDs de assinatura.

#### **Kubernetes**

- **`deploy.yml`**:
- **Deployment**:
- Define como a aplicação F# será implantada no Kubernetes, incluindo a configuração da imagem Docker e os recursos necessários.
- **Service**:
- Define como a aplicação será exposta externamente usando um LoadBalancer.

#### **GitHub Actions**

- **`.github/workflows/kubernetes.yml`**:
- **Build Job**:
- Configura o Docker Buildx.
- Faz login no DockerHub usando credenciais armazenadas em segredos.
- Constrói e faz push da imagem Docker para o DockerHub.
- **Deploy Job**:
- Configura o `kubectl` para interagir com o cluster Kubernetes.
- Aplica o arquivo `deploy.yml` para realizar o deploy da aplicação no Kubernetes.

- **`terra.yml`**:
- **Terraform Job**:
- Configura o Terraform para executar o `terraform plan` e verificar as mudanças na infraestrutura.
- Usa variáveis de ambiente para autenticação com Azure.

---
26 changes: 26 additions & 0 deletions infraservices/k8s/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: fsharp-app
spec:
replicas: 1
selector:
matchLabels:
app: fsharp-app
template:
metadata:
labels:
app: fsharp-app
spec:
containers:
- name: fsharp-app
image: docker.io/yurilinc/fsharp-app
ports:
- containerPort: 8085
resources:
limits:
memory: "512Mi"
cpu: "500m"
requests:
memory: "256Mi"
cpu: "250m"
12 changes: 12 additions & 0 deletions infraservices/k8s/service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: fsharp-service
spec:
selector:
app: fsharp-app
ports:
- protocol: TCP
port: 80
targetPort: 8085
type: LoadBalancer
67 changes: 67 additions & 0 deletions infraservices/terras/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
resource "azurerm_resource_group" "grn" {
name = var.resource_group_name
location = var.location
}

resource "azurerm_virtual_network" "vnet" {
name = var.vnet_name
location = azurerm_resource_group.grn.location
resource_group_name = azurerm_resource_group.grn.name
address_space = ["10.0.0.0/16"]
}

resource "azurerm_subnet" "subnet" {
name = var.subnet_name
resource_group_name = azurerm_resource_group.grn.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.1.0/24"]
}

resource "azurerm_network_interface" "nic" {
name = "${var.vnet_name}-nic"
location = azurerm_resource_group.grn.location
resource_group_name = azurerm_resource_group.grn.name

ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.pip.id
}
}

resource "azurerm_linux_virtual_machine" "vm" {
name = "datapi-vm"
resource_group_name = azurerm_resource_group.grn.name
location = azurerm_resource_group.grn.location
size = "Standard_F2"
admin_username = var.admin_username
disable_password_authentication = false
network_interface_ids = [
azurerm_network_interface.nic.id,
]

admin_ssh_key {
username = var.admin_username
public_key = file("../token/id_rsa.pub")
}

source_image_reference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts"
version = "latest"
}

os_disk {
storage_account_type = "Standard_LRS"
caching = "ReadWrite"
}
}

resource "azurerm_public_ip" "pip" {
name = "publicip-pip"
resource_group_name = azurerm_resource_group.grn.name
location = azurerm_resource_group.grn.location
allocation_method = "Static"
}
19 changes: 19 additions & 0 deletions infraservices/terras/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
output "resource_group_name" {
description = "Name of resouce group"
value = azurerm_resource_group.grn.name
}

output "virtual_network_name" {
description = "VNET name"
value = azurerm_virtual_network.vnet.name
}

output "subnet_id" {
description = "ID Subnet"
value = azurerm_subnet.subnet.id
}

output "vm_public_ip" {
description = "Public address"
value = azurerm_linux_virtual_machine.vm.public_ip_address
}
Loading