Como fazer deploy de uma aplicação Go no Google Cloud Run com Github Actions

Como fazer deploy de uma aplicação Go no Google Cloud Run com Github Actions

Eai galera!

Nesse post, o objetivo é mostrar que nem sempre é preciso um Kubernetes ou Jenkins para colocar as suas aplicações no ar.

Vamos criar uma Instância no Cloud Run do Google, criar uma Pipeline utilizando o Github Actions e fazer o deploy de uma aplicação bem simples, com testes e tudo mais.

Então, para começar, vamos criar uma API, tipo Hello World em Go, com testes.

Estou assumindo que você já tenha o Go instalado e o GCloud CLI.

Link para instalação do Go: https://go.dev/doc/install

Link para a instalação do GCloud CLI: https://cloud.google.com/sdk/gcloud

Aplicação em Go

Crie um arquivo chamado main.go, que deverá ter o seguinte conteúdo:

package main

import (
“net/http”

“github.com/labstack/echo/v4”
)

func Exemplo(c echo.Context) error {
return c.String(http.StatusOK, “Exemplo 4Linux”)
}
func main() {
e := echo.New()
e.GET(“/”, Exemplo)
e.Logger.Fatal(e.Start(“:1323”))
}

 

O código acima apenas retornará a frase “Exemplo 4Linux” no seu navegador.

Para executar o código, primeiro você precisa criar um módulo para a sua aplicação, utilizando o comando go mod init

(base) alissonmachado@Alissons-Air go_post % go mod init exemplo_4linux
go: creating new go.mod: module exemplo_4linux
go: to add module requirements and sums:
go mod tidy

E então, go mod tidy para fazer o download das dependências, que no nosso caso é o Echo Framework, o que seria equivalente ao Flask que temos no Python. Existem diversos outros frameworks para linguagem Go, mas esse é o meu preferido.

(base) alissonmachado@Alissons-Air go_post % go mod tidy
go: finding module for package github.com/labstack/echo/v4
go: found github.com/labstack/echo/v4 in github.com/labstack/echo/v4 v4.7.2

Para executar a aplicação, execute go run main.go. Esse comando irá compilar e executar o seu código, então acesse no navegador, http://localhost:1323

(base) alissonmachado@Alissons-Air go_post % go run main.go

____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.7.2
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:1323

Agora que a aplicação já está rodando, precisamos criar um teste para validar se a aplicação está trazendo a resposta correta.

Crie um arquivo chamada main_test.go, com o código abaixo:

package main

import (
“net/http”
“net/http/httptest”
“testing”

“github.com/labstack/echo/v4”
“github.com/stretchr/testify/assert”
)

func TestMain(t *testing.T) {
e := echo.New()

req := httptest.NewRequest(http.MethodGet, “/”, nil)
rec := httptest.NewRecorder()

c := e.NewContext(req, rec)

Exemplo(c)

assert.Equal(t, http.StatusOK, rec.Code)
assert.Equal(t, “Exemplo 4Linux”, rec.Body.String())

}

 

O código acima irá chamar a nossa função Exemplo e verificar se o status code da resposta é OK (200), e se o conteúdo da resposta (Response Body) é igual a Exemplo 4linux. Caso positivo os testes irão passar.

Execute novamente go mod tidy para baixar os novos módulos, e go test. Automaticamente o go irá procurar por arquivos _test.go e irá executá-los.

(base) alissonmachado@Alissons-Air go_post % go test
PASS
ok exemplo_4linux 0.116s

Deploy no Cloud Run
Beleza! Agora que já temos a nossa aplicação, vamos colocá-la em produção manual, pois precisamos saber como compilar e como executá-la dentro do Cloud Run, e então saberemos como automatizar e colocar em uma pipeline.

Logue no gcloud com o comando gcloud init.

Você deve seguir as instruções que forem mostradas na tela, isso vai ser diferente para cada um, no meu caso foi assim:

Your current configuration has been set to: [blog]

You can skip diagnostics next time by using the following flag:
gcloud init –skip-diagnostics

Network diagnostic detects and fixes local network connection issues.
Checking network connection…done.
Reachability Check passed.
Network diagnostic passed (1/1 checks passed).

Choose the account you would like to use to perform operations for this configuration:
[1] alisson.itops@gmail.com
[2] alisson.machado@4linux.com.br
[3] Log in with a new account
Please enter your numeric choice: 1

You are logged in as: [alisson.itops@gmail.com].

Pick cloud project to use:
[1] blog-357212
[2] culturadocaractere
[3] Enter a project ID
[4] Create a new project
Please enter numeric choice or text value (must exactly match list item): 1

Your current project has been set to: [blog-357212].

Your Google Cloud SDK is configured and ready to use!

* Commands that require authentication will use alisson.itops@gmail.com by default
* Commands will reference project `blog-357212` by default
Run `gcloud help config` to learn how to change individual settings

This gcloud configuration is called [blog]. You can create additional configurations if you work with multiple accounts and/or projects.

O Cloud Run é um serviço do Google Cloud que te permite executar containers, onde você deve criar uma imagem com a sua aplicação, informar qual é essa imagem e o Cloud run vai baixá-la e executá-la automaticamente.

O primeiro passo será criar um Dockerfile para fazer o build dessa imagem.

# Build Container
FROM golang:1.18-buster as builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . ./
RUN go build -mod=readonly -v -o server

# Application Container
FROM debian:buster-slim
RUN mkdir /app
RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
ca-certificates && \
rm -rf /var/lib/apt/lists/*
COPY –from=builder /app/server /app/server
CMD [“/app/server”]

Esse Dockerfile pode ser encontrado na documentação oficial do Cloud run, e ele vai variar dependendo da linguagem de programação que você usa.

O Google Cloud também tem um serviço chamado Cloud Build, então não precisamos fazer o build da nossa imagem localmente, basta executar o seguinte comando:

gcloud builds submit –tag gcr.io/blog-357212/exemplo-go

DONE
————————————————————————————————————————————————
ID CREATE_TIME DURATION SOURCE IMAGES STATUS
b44e61e6-ff1a-4344-ac25-3aa662fbd59c 2022-07-23T14:01:20+00:00 1M2S gs://blog-357212_cloudbuild/source/1658584837.191657-65b6a13056a7497d9e7526477d8c3b8d.tgz gcr.io/blog-357212/exemplo-go (+1 more) SUCCESS

Ao finalizar a execução, você verá que já tem uma nova imagem armazenada no seu container registry:

https://console.cloud.google.com/gcr/images/

Agora podemos fazer o deploy dessa aplicação.

Para isso execute o seguinte comando:

gcloud run deploy exemplo-go –image=gcr.io/blog-357212/exemplo-go –allow-unauthenticated –port=1323

Deploying container to Cloud Run service [exemplo-go] in project [blog-357212] region [europe-west1]
✓ Deploying new service… Done.
✓ Creating Revision…
✓ Routing traffic…
✓ Setting IAM Policy…
Done.
Service [exemplo-go] revision [exemplo-go-00001-wal] has been deployed and is serving 100 percent of traffic.
Service URL: https://exemplo-go-xpt4gb4afa-ew.a.run.app

 

Veja que a aplicação já está em execução no endereço: https://exemplo-go-xpt4gb4afa-ew.a.run.app e já tem o https configurado.

Agora que já sabemos como fazer tudo, vamos criar a pipeline.

Criando a pipeline no Github Actions

Dentro do seu repositório no github, em .github/workflows, crie um arquivo chamado deploy.yml, com o seguinte conteúdo:

name: CI / CD

on:
push:
branches: [ main ]

jobs:

BuildAndDeploy:
runs-on: ubuntu-latest

steps:
– uses: actions/checkout@v3
– name: Set up Go 1.18
uses: actions/setup-go@v1
with:
go-version: 1.18
id: go

– name: Testing the application
run: |
go test

– name: ‘Set up Cloud SDK’
uses: ‘google-github-actions/setup-gcloud@v0’

– id: ‘auth’
uses: ‘google-github-actions/auth@v0’
with:
credentials_json: ‘${{ secrets.GCP_SA_KEY}}’

– name: Build & Publish
run: |
gcloud config set project blog-357212
gcloud builds submit –tag gcr.io/blog-357212/exemplo-go
gcloud config set run/region europe-west1

– name: Cloud Run
uses: google-github-actions/deploy-cloudrun@v0
with:
flags: “–port=1323”
image: gcr.io/blog-357212/exemplo-go:latest
service: exemplo-go

Todos os comandos que utilizamos anteriormente estão presentes nesse arquivo, mas note que temos uma secret definida.

credentials_json: ‘${{ secrets.GCP_SA_KEY}}’

Essa é a sua chave de autenticação do Github com o Gcloud, então precisamos gerar essa chave e definir como secret dentro do nosso repositório.

Para fazer isso, acesse a parte de service accounts do GCP:

https://console.cloud.google.com/iam-admin/serviceaccounts

Eu criei uma service account chamada exemplo-go, com a permissão de Owner, o que é inseguro, mas como eu só quero mostrar a pipeline, assim vai ser mais fácil.

Clique em Keys e crie uma chave do tipo JSON.

Você fará automaticamente o download dessa chave no formato json, mas não precisa se preocupar com o conteúdo, afinal, isso será armazenado no Github, lembrando que as Secrets só aceitam valores do tipo texto.

Então, vamos converter essa chave em formato base64.

cat blog-357212-88f09f4b1a2e.json | base64

Acesse o seu repositório, vá em configurações, secrets e adicione o valor conforme a imagem:

Agora faça um commit e um push do código para o repositório, e você verá que a pipeline será executada automaticamente e o deploy será feito no GCP.

Líder em Treinamento e serviços de Consultoria, Suporte e Implantação para o mundo open source. Conheça nossas soluções:

CURSOSCONSULTORIA

Anterior Conexão com Cluster Kafka Hospedado em Kubernetes: Guia Completo
Próxima Como usar o Kaniko para criar imagens de contêineres no GitLab CI/CD

About author

Alisson Machado
Alisson Machado 22 posts

Alisson Menezes, atua como Gerente de T.I, 9 anos de experiência em projetos FOSS (Free and Open Source Software) e Python. Formação em Análise de Sistemas pela FMU e cursando MBA em BigData pela FIA, possui certificações LPI1, LPI2 e SUSE CLA, LPI DevOps e Exim - DevOps Professional. Autor dos cursos Python Fundamentals, Python for Sysadmins, MongoDB for Developers/DBAs, DevSecOps, Co-Autor do Infraestrutura Ágil e Docker da 4Linux e palestrantes em eventos como FISL, TDC e Python Brasil. É entusiasta das mais diversas áreas em T.I como Segurança, Bancos de dados NoSQL, DataScience mas tem como foco DevOps e Automação.

View all posts by this author →

Você pode gostar também

Segurança

Proteja sua infraestrutura com Ansible Vault: segurança e simplicidade

Automatize sua infraestrutura sem correr riscos de segurança O Ansible foi um dos responsáveis pela popularização da automação de configurações por meio das suas playbooks (scripts no formato YAML, onde

Desenvolvimento

Guia completo para instalação do Gitea: Ferramenta open source de gerenciamento de código-fonte

O Gitea é uma ferramenta open source de Source Code Management – SCM, ou seja, gerenciamento de código-fonte, escrita em Go e que foi criada em novembro de 2016 além

DevOps

Guia prático: Acelere o Time To Market com DevOps e Vagrant

Conheça como criar máquinas virtuais com o Vagrant e crie ambientes padronizados iniciando pelo de Desenvolvimento. DevOps tem como objetivo diminuir o Time To Market de um serviço, ou seja,