{"id":4540,"date":"2022-05-27T13:58:00","date_gmt":"2022-05-27T11:58:00","guid":{"rendered":"https:\/\/blog.besharp.it\/?p=4540"},"modified":"2022-06-30T15:32:21","modified_gmt":"2022-06-30T13:32:21","slug":"un-approccio-serverless-per-lintegrazione-con-gitlab-su-aws","status":"publish","type":"post","link":"https:\/\/blog.besharp.it\/it\/un-approccio-serverless-per-lintegrazione-con-gitlab-su-aws\/","title":{"rendered":"Un approccio serverless per l’integrazione con GitLab su AWS"},"content":{"rendered":"\n

L\u2019ottimizzazione dei costi e l\u2019eccellenza operativa sono fattori determinanti per una strategia vincente, che porti all\u2019adozione del paradigma Cloud. I servizi gestiti serverless consentono di ridurre drasticamente i costi e di velocizzare le operazioni di mantenimento dell\u2019infrastruttura.<\/p>\n\n\n\n

In questo articolo descriveremo come integrare le pipeline GitLab su AWS usando ECS Fargate in uno scenario multi-ambiente.<\/p>\n\n\n\n

GitLab, per quanto riguarda l\u2019utilizzo di risorse computazionali, offre una grande flessibilit\u00e0: le pipeline possono essere eseguite da cluster Kuberenetes, Docker, su virtual machine on prem o su piattaforme personalizzate usando driver custom.<\/p>\n\n\n\n

La soluzione pi\u00f9 diffusa per l\u2019esecuzione di pipeline sul Cloud AWS prevede l\u2019utilizzo di istanze EC2. Questo approccio porta ad alcune inefficienze: avviare le istanze on-demand aumenta il tempo di esecuzione, rendendo impazienti gli sviluppatori (a causa del tempo di inizializzazione). Tenere attive istanze \u201cdi scorta\u201d durante la giornata disponibili per le build, di contro, aumenta i costi. <\/p>\n\n\n\n

Il nostro obiettivo \u00e8 trovare una soluzione che possa ridurre il tempo di esecuzione, facilitare la manutenzione e ottimizzare i costi.<\/p>\n\n\n\n

I container, ad esempio, hanno un tempo di avvio breve e aiutano a contenere i costi: in questo caso d\u2019uso il billing sarebbe proporzionale solamente al tempo di esecuzione effettivamente utilizzato. <\/p>\n\n\n\n

Per raggiungere il nostro obiettivo faremo in modo di eseguire su task ECS Fargate le nostre build. In aggiunta vedremo anche come utilizzare i servizi ECS per implementarle e gestirne l\u2019autoscaling. <\/p>\n\n\n\n

Prima di passare all\u2019implementazione pratica una piccola premessa: GitLab, per eseguire gli script definiti nelle pipeline, utilizza un agent software chiamato GitLab Runner, possiamo configurare una istanza del runner dedicata alla gestione dello scaling che si occupi di aggiungere e rimuovere risorse computazionali in base all\u2019andamento delle richieste.<\/p>\n\n\n\n

Nei nostri esempi assumeremo che siano utilizzati tre ambienti: sviluppo (dev), test (staging) e produzione (prod), utilizzeremo ruoli IAM differenti per i nostri runner per limitare i permessi assegnati ed utilizzare il principio di least privilege.<\/p>\n\n\n\n

I runner GitLab possono essere associati a tag che rendono possibile la scelta dell\u2019ambiente in cui verranno eseguite le build.<\/p>\n\n\n\n

In questo esempio \u00e8 definita una pipeline che compila e fa il deploy in 3 ambienti differenti:<\/p>\n\n\n\n

stages: \n - build dev\n - deploy dev \n - build staging\n - deploy staging\n - build production\n - deploy production\n \nbuild-dev: \n stage: build dev \n tags: \n   - dev \n script: \n   - .\/scripts\/build.sh\n artifacts: \n   paths: \n     - .\/artifacts\n   expire_in: 7d \n  \ndeploy-dev: \n stage: deploy dev \n tags: \n   - dev \n script: \n   - .\/scripts\/deploy.sh\n\nbuild-staging: \n stage: build staging\n tags: \n   - staging\n script: \n   - .\/scripts\/build.sh\n artifacts: \n   paths: \n     - .\/artifacts\n   expire_in: 7d \n\n deploy-staging: \n stage: deploy staging\n tags: \n   - staging\n script: \n   - .\/scripts\/deploy.sh\n\nbuild-production: \n stage: build production\n tags: \n   - production\n script: \n   - .\/scripts\/build.sh\n artifacts: \n   paths: \n     - .\/artifacts\n   expire_in: 7d \n\n deploy-production: \n stage: deploy production\n tags: \n   - production\n script: \n   - .\/scripts\/deploy.sh\n<\/code><\/pre>\n\n\n\n

Implementare un runner Fargate base<\/strong><\/h2>\n\n\n\n

Assumendo che il nostro software sia scritto utilizzando NodeJS possiamo sviluppare un Dockerfile che permetta di fare la build di una immagine Docker contenente tutte le dipendenze (GitLab runner incluso).<\/p>\n\n\n\n

Dockerfile<\/strong><\/p>\n\n\n\n

# Ubuntu based GitLab runner with nodeJS, npm, and aws CLI \n# --------------------------------------------------------------------- \n# Install https:\/\/github.com\/krallin\/tini - a very small 'init' process \n# that helps process signals sent to the container properly. \n# --------------------------------------------------------------------- \nARG TINI_VERSION=v0.19.0 \n \nCOPY docker-entrypoint.sh \/usr\/local\/bin\/docker-entrypoint.sh \n \nRUN ln -snf \/usr\/share\/zoneinfo\/Europe\/Rome \/etc\/localtime && echo Europe\/Rome > \/etc\/timezone \\ \n   && echo \"Installing base packaes\" \\ \n   && apt update && apt install -y curl gnupg unzip jq software-properties-common \\ \n   && echo \"Installing awscli\" \\ \n   && curl \"https:\/\/awscli.amazonaws.com\/awscli-exe-linux-x86_64.zip\" -o \"awscliv2.zip\" \\ \n   && unzip awscliv2.zip \\ \n   && .\/aws\/install \\ \n   && rm -f awscliv2.zip \\ \n   && apt update \\ \n   && echo \"Installing packages\" \\ \n   && apt install -y unzip openssh-server ca-certificates git git-lfs nodejs npm \\ \n   && echo \"Installing tini and ssh\" \\ \n   && curl -Lo \/usr\/local\/bin\/tini https:\/\/github.com\/krallin\/tini\/releases\/download\/${TINI_VERSION}\/tini-amd64 \\ \n   && chmod +x \/usr\/local\/bin\/tini \\ \n   && mkdir -p \/run\/sshd \\ \n   && curl -L https:\/\/packages.gitlab.com\/install\/repositories\/runner\/gitlab-runner\/script.deb.sh | bash \\ \n       && apt install -y gitlab-runner \\ \n       && rm -rf \/var\/lib\/apt\/lists\/* \\ \n       && rm -f \/home\/gitlab-runner\/.bash_logout \\ \n   && git lfs install --skip-repo \\ \n   && chmod +x \/usr\/local\/bin\/docker-entrypoint.sh \\ \n   && echo \"Done\"\n\nEXPOSE 22 \n \nENTRYPOINT [\"tini\", \"--\", \"\/usr\/local\/bin\/docker-entrypoint.sh\"]<\/code><\/pre>\n\n\n\n

docker-entrypoint.sh<\/strong><\/p>\n\n\n\n

#!\/bin\/sh \n \n# Create a folder to store the user's SSH keys if it does not exist. \nUSER_SSH_KEYS_FOLDER=~\/.ssh \n[ ! -d ${USER_SSH_KEYS_FOLDER} ] && mkdir -p ${USER_SSH_KEYS_FOLDER} \n \n# Copy contents from the `SSH_PUBLIC_KEY` environment variable \n# to the `$USER_SSH_KEYS_FOLDER\/authorized_keys` file. \n# The environment variable must be set when the container starts. \necho \"${SSH_PUBLIC_KEY}\" > ${USER_SSH_KEYS_FOLDER}\/authorized_keys \n \n# Clear the `SSH_PUBLIC_KEY` environment variable. \nunset SSH_PUBLIC_KEY \n \n# Start the SSH daemon \n\/usr\/sbin\/sshd -D<\/code><\/pre>\n\n\n\n

<\/p>\n\n\n\n

<\/p>\n\n\n\n

In questo caso non c\u2019\u00e8 nessuna dipendenza dall\u2019ambiente in cui l\u2019immagine dovr\u00e0 essere eseguita.<\/p>\n\n\n\n

 Implementare un runner per l\u2019autoscaling (Runner Manager)<\/strong><\/p>\n\n\n\n

Questo tipo di runner deve essere specializzato per poter gestire l\u2019ambiente in cui dovr\u00e0 essere eseguito: adotteremo il Fargate custom executor sviluppato da GitLab per utilizzare cluster ECS Fargate differenti per i nostri ambienti.<\/p>\n\n\n\n

La registrazione del nostro runner con il server GitLab sar\u00e0 automatizzata ed eseguita durante la fase di build, usando variabili per specificare il token e gli altri parametri di configurazione.<\/p>\n\n\n\n

Il custom executor Fargate necessita di un file di configurazione (\u201cconfig.toml\u201d) per poter specificare il cluster, le subnet, i security groups e la task definition da utilizzare per l\u2019esecuzione della pipeline. Faremo in modo di automatizzare anche questa configurazione nella fase di build del container.<\/p>\n\n\n\n

Per prima cosa dobbiamo ottenere un token per la registrazione del runner con il server GitLab.<\/p>\n\n\n\n

Alla sezione \u201cCI\/CD\u201d nelle impostazioni del progetto si pu\u00f2 espandere la sezione \u201cRunners\u201d.<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

Gli unici dati necessari sono il registration Token e l\u2019indirizzo del server GitLab.<\/p>\n\n\n\n

L\u2019indirizzo del server GitLab pu\u00f2 essere anche inserito direttamente nel Dockerfile, tratteremo invece il token di registrazione come un segreto.<\/p>\n\n\n\n

Queste righe, contenute nel Dockerfile, si occupano della modifica del file di configurazione<\/p>\n\n\n\n

RUNNER_TASK_TAGS=$(echo ${RUNNER_TAGS} | tr \",\" \"-\") \nsed -i s\/RUNNER_TAGS\/${RUNNER_TASK_TAGS}\/g \/tmp\/ecs.toml \nsed -i s\/SUBNET\/${SUBNET}\/g \/tmp\/ecs.toml\nsed -i s\/SECURITY_GROUP_ID\/${SECURITY_GROUP_ID}\/g \/tmp\/ecs.toml<\/code><\/pre>\n\n\n\n

DockerFile<\/strong><\/p>\n\n\n\n

FROM ubuntu:20.04 \n \nARG GITLAB_TOKEN \nARG RUNNER_TAGS \nARG GITLAB_URL=\"https:\/\/gitlab.myawesomecompany.com\" \nARG SUBNET\nARG SECURITY_GROUP_ID \n \n \nCOPY config.toml \/tmp\/ \nCOPY ecs.toml \/tmp\/ \nCOPY entrypoint \/ \nCOPY fargate-driver \/tmp \n \n \nRUN apt update && apt install -y curl unzip \\ \n       && curl -L https:\/\/packages.gitlab.com\/install\/repositories\/runner\/gitlab-runner\/script.deb.sh | bash \\ \n       && apt install -y gitlab-runner \\ \n       && rm -rf \/var\/lib\/apt\/lists\/* \\ \n       && rm -f \"\/home\/gitlab-runner\/.bash_logout\" \\ \n       && chmod +x \/entrypoint \\ \n       && mkdir -p \/opt\/gitlab-runner\/metadata \/opt\/gitlab-runner\/builds \/opt\/gitlab-runner\/cache \\ \n       && curl -Lo \/opt\/gitlab-runner\/fargate https:\/\/gitlab-runner-custom-fargate-downloads.s3.amazonaws.com\/latest\/fargate-linux-amd64 \\ \n       && chmod +x \/opt\/gitlab-runner\/fargate \\ \n       && RUNNER_TASK_TAGS=$(echo ${RUNNER_TAGS} | tr \",\" \"-\") \\ \n       && sed -i s\/RUNNER_TAGS\/${RUNNER_TASK_TAGS}\/g \/tmp\/ecs.toml \\ \n       && sed -i s\/SUBNET\/${SUBNET}\/g \/tmp\/ecs.toml \\ \n       && sed -i s\/SECURITY_GROUP_ID\/${SECURITY_GROUP_ID}\/g \/tmp\/ecs.toml \\ \n       && cp \/tmp\/ecs.toml \/etc\/gitlab-runner\/ \\ \n       && echo \"Token: ${GITLAB_TOKEN} url: ${GITLAB_URL} Tags: ${RUNNER_TAGS}\" \\ \n       && gitlab-runner register \\ \n               --non-interactive \\ \n               --url ${GITLAB_URL} \\ \n               --registration-token ${GITLAB_TOKEN} \\ \n               --template-config \/tmp\/config.toml \\ \n               --description \"GitLab runner for ${RUNNER_TAGS}\" \\ \n               --executor \"custom\" \\ \n               --tag-list ${RUNNER_TAGS} \n \nENTRYPOINT [\"\/entrypoint\"] \nCMD [\"run\", \"--user=gitlab-runner\", \"--working-directory=\/home\/gitlab-runner\"]<\/code><\/pre>\n\n\n\n

A questo punto possiamo fare la build del container:<\/p>\n\n\n\n

docker build . -t gitlab-runner --build-arg GITLAB_TOKEN=\"generatedgitlabtoken\" --build-arg RUNNER_TAGS=\"dev\" --build-arg SUBNET=\"subnet-12345\" --build-arg SECURITY_GROUP_ID=\"sg-12345\"<\/code><\/pre>\n\n\n\n

Queste linee nel Dockerfile si occupano della personalizzazione del file di configurazione:<\/p>\n\n\n\n

RUNNER_TASK_TAGS=$(echo ${RUNNER_TAGS} | tr \",\" \"-\") \nsed -i s\/RUNNER_TAGS\/${RUNNER_TASK_TAGS}\/g \/tmp\/ecs.toml \nsed -i s\/SUBNET\/${SUBNET}\/g \/tmp\/ecs.toml\nsed -i s\/SECURITY_GROUP_ID\/${SECURITY_GROUP_ID}\/g \/tmp\/ecs.toml<\/code><\/pre>\n\n\n\n

DockerFile<\/strong><\/p>\n\n\n\n

FROM ubuntu:20.04 \n \nARG GITLAB_TOKEN \nARG RUNNER_TAGS \nARG GITLAB_URL=\"https:\/\/gitlab.myawesomecompany.com\" \nARG SUBNET\nARG SECURITY_GROUP_ID \n \n \nCOPY config.toml \/tmp\/ \nCOPY ecs.toml \/tmp\/ \nCOPY entrypoint \/ \nCOPY fargate-driver \/tmp \n \n \nRUN apt update && apt install -y curl unzip \\ \n       && curl -L https:\/\/packages.gitlab.com\/install\/repositories\/runner\/gitlab-runner\/script.deb.sh | bash \\ \n       && apt install -y gitlab-runner \\ \n       && rm -rf \/var\/lib\/apt\/lists\/* \\ \n       && rm -f \"\/home\/gitlab-runner\/.bash_logout\" \\ \n       && chmod +x \/entrypoint \\ \n       && mkdir -p \/opt\/gitlab-runner\/metadata \/opt\/gitlab-runner\/builds \/opt\/gitlab-runner\/cache \\ \n       && curl -Lo \/opt\/gitlab-runner\/fargate https:\/\/gitlab-runner-custom-fargate-downloads.s3.amazonaws.com\/latest\/fargate-linux-amd64 \\ \n       && chmod +x \/opt\/gitlab-runner\/fargate \\ \n       && RUNNER_TASK_TAGS=$(echo ${RUNNER_TAGS} | tr \",\" \"-\") \\ \n       && sed -i s\/RUNNER_TAGS\/${RUNNER_TASK_TAGS}\/g \/tmp\/ecs.toml \\ \n       && sed -i s\/SUBNET\/${SUBNET}\/g \/tmp\/ecs.toml \\ \n       && sed -i s\/SECURITY_GROUP_ID\/${SECURITY_GROUP_ID}\/g \/tmp\/ecs.toml \\ \n       && cp \/tmp\/ecs.toml \/etc\/gitlab-runner\/ \\ \n       && echo \"Token: ${GITLAB_TOKEN} url: ${GITLAB_URL} Tags: ${RUNNER_TAGS}\" \\ \n       && gitlab-runner register \\ \n               --non-interactive \\ \n               --url ${GITLAB_URL} \\ \n               --registration-token ${GITLAB_TOKEN} \\ \n               --template-config \/tmp\/config.toml \\ \n               --description \"GitLab runner for ${RUNNER_TAGS}\" \\ \n               --executor \"custom\" \\ \n               --tag-list ${RUNNER_TAGS} \n \nENTRYPOINT [\"\/entrypoint\"] \nCMD [\"run\", \"--user=gitlab-runner\", \"--working-directory=\/home\/gitlab-runner\"]<\/code><\/pre>\n\n\n\n

Per la build del runner manager \u00e8 sufficiente eseguire:<\/p>\n\n\n\n

docker build . -t gitlab-runner-manager --build-arg GITLAB_TOKEN=\"generatedgitlabtoken\" --build-arg RUNNER_TAGS=\"dev\" --build-arg SUBNET=\"subnet-12345\" --build-arg SECURITY_GROUP_ID=\"sg-12345\"<\/code><\/pre>\n\n\n\n

Al termine delle operazioni, il runner si registrer\u00e0:<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

config.toml<\/strong><\/p>\n\n\n\n

concurrent = 1 \ncheck_interval = 0 \n \n[session_server] \n session_timeout = 1800 \n \n[[runners]] \n name = \"ec2-ecs\" \n executor = \"custom\" \n builds_dir = \"\/opt\/gitlab-runner\/builds\" \n cache_dir = \"\/opt\/gitlab-runner\/cache\" \n [runners.cache] \n   [runners.cache.s3] \n   [runners.cache.gcs] \n [runners.custom] \n   config_exec = \"\/opt\/gitlab-runner\/fargate\" \n   config_args = [\"--config\", \"\/etc\/gitlab-runner\/ecs.toml\", \"custom\", \"config\"] \n   prepare_exec = \"\/opt\/gitlab-runner\/fargate\" \n   prepare_args = [\"--config\", \"\/etc\/gitlab-runner\/ecs.toml\", \"custom\", \"prepare\"] \n   run_exec = \"\/opt\/gitlab-runner\/fargate\" \n   run_args = [\"--config\", \"\/etc\/gitlab-runner\/ecs.toml\", \"custom\", \"run\"] \n   cleanup_exec = \"\/opt\/gitlab-runner\/fargate\" \n   cleanup_args = [\"--config\", \"\/etc\/gitlab-runner\/ecs.toml\", \"custom\", \"cleanup\"]<\/code><\/pre>\n\n\n\n

ecs.toml<\/strong><\/p>\n\n\n\n

LogLevel = \"info\" \nLogFormat = \"text\" \n \n[Fargate] \n Cluster = \"acme-gitlab-RUNNER-TAGS-cluster\" \n Region = \"eu-west-1\" \n Subnet = \"SUBNET\"\n SecurityGroup = \"SECURITY_GROUP_ID\"\n TaskDefinition = \"gitlab-runner-RUNNER_TAGS-task\" \n EnablePublicIP = false \n \n[TaskMetadata] \n Directory = \"\/opt\/gitlab-runner\/metadata\" \n \n[SSH] \n Username = \"root\" \n Port = 22<\/code><\/pre>\n\n\n\n

entrypoint<\/strong><\/p>\n\n\n\n

!\/bin\/bash\n\n# gitlab-runner data directory\nDATA_DIR=\"\/etc\/gitlab-runner\"\nCONFIG_FILE=${CONFIG_FILE:-$DATA_DIR\/config.toml}\n# custom certificate authority path\nCA_CERTIFICATES_PATH=${CA_CERTIFICATES_PATH:-$DATA_DIR\/certs\/ca.crt}\nLOCAL_CA_PATH=\"\/usr\/local\/share\/ca-certificates\/ca.crt\"\n\nupdate_ca() {\n  echo \"Updating CA certificates...\"\n  cp \"${CA_CERTIFICATES_PATH}\" \"${LOCAL_CA_PATH}\"\n  update-ca-certificates --fresh >\/dev\/null\n}\n\nif [ -f \"${CA_CERTIFICATES_PATH}\" ]; then\n  # update the ca if the custom ca is different than the current\n  cmp --silent \"${CA_CERTIFICATES_PATH}\" \"${LOCAL_CA_PATH}\" || update_ca\nfi\n\n# launch gitlab-runner passing all arguments\nexec gitlab-runner \"$@\"<\/code><\/pre>\n\n\n\n

Terminata la fase di build dobbiamo trasferire l\u2019immagine nei repositoyi ECR (utilizzeremo gitlab-runner e gitlab-runner-autoscaling come nome), le istruzioni per la fase di push delle immagini docker sono disponibili nella documentazione del servizio ECR.<\/p>\n\n\n\n

<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

Una volta completata questa fase, possiamo procedere alla configurazione delle Task Definition<\/p>\n\n\n\n

Ci occuperemo solamente la configurazione dell\u2019ambiente di sviluppo, le operazioni per test e produzione sono simili.<\/p>\n\n\n\n

In questo articolo<\/a> \u00e8 possibile trovare una guida pi\u00f9 dettagliata per la creazione di repository ECR e task definition.<\/p>\n\n\n\n

Configureremo le task definition per eseguire i runner nei nostri ambienti (gitlab-runner-dev-task, gitlab-runner-stage-task, gitlab-runner-prod-task).Attenzione: la task definition deve includere un container con nome “ci-coordinator<\/strong>“. Occorre anche definire un port mapping per la porta 22 ed un security group che permetta le connessioni in entrata su quella porta: GitLab utilizza infatti una connessione ssh per l’esecuzione delle fasi della pipeline.<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

Una volta terminata la configurazione della task definition per il runner possiamo procedere con la parte dedicata all’autoscaling.<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

A questo punto basta aggiungere un ECS Service che si pu\u00f2 occupare di gestire il runner.<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

Occorre anche definire un ruolo con una policy associata che permetta l’esecuzione di task nel cluster:<\/p>\n\n\n\n

{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"AllowRunTask\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"ecs:RunTask\",\n                \"ecs:ListTasks\",\n                \"ecs:StartTask\",\n                \"ecs:StopTask\",\n                \"ecs:ListContainerInstances\",\n                \"ecs:DescribeTasks\"\n            ],\n            \"Resource\": [\n                \"arn:aws:ecs:eu-west-1:account-id:task\/acme-gitlab-dev-cluster\/*\",\n                \"arn:aws:ecs:eu-west-1:account-id:cluster\/acme-gitlab-dev-cluster\",\n                \"arn:aws:ecs:eu-west-1:account-id:task-definition\/*:*\",\n                \"arn:aws:ecs:*:account-id:container-instance\/*\/*\"\n            ]\n        },\n        {\n            \"Sid\": \"AllowListTasks\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"ecs:ListTaskDefinitions\",\n                \"ecs:DescribeTaskDefinition\"\n            ],\n            \"Resource\": \"*\"\n        }\n    ]\n}\n<\/code><\/pre>\n\n\n\n

Dopo un minuto il nostro servizio sar\u00e0 disponibile:<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

A questo punto possiamo definire una pipeline di test in .gitlab-ci.yml<\/p>\n\n\n\n

test:\n  tags:\n    - dev\n  script:\n  - echo \"It works!\"\n  - for i in $(seq 1 30); do echo \".\"; sleep 1; done\n<\/code><\/pre>\n\n\n\n

Il runner avvier\u00e0 un nuovo task per l’esecuzione della pipeline<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

Il task passer\u00e0 in stato running e l’esecuzione inizier\u00e0:<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

E l’esecuzione terminer\u00e0 con successo!<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

Terminata la pipeline il container non sar\u00e0 pi\u00f9 in esecuzione.<\/p>\n\n\n\n

Troubleshooting<\/strong><\/p>\n\n\n\n

Nel caso si verifichi un errore di timeout verificare i security group ed il routing dalle subnet ai repository ECR (se sono in uso subnet private). Nel caso di subnet isolate occorre invece aggiungere un VPC endpoint per accedere al servizio ECR.
Nel caso l’errore sia: “starting new Fargate task: running new task on Fargate: error starting AWS Fargate Task: InvalidParameterException: No Container Instances were found in your cluster<\/em>.”  occorre verificare che sia definito un capacity provider di default per il cluster ECS (fare click su “Update Cluster” e selezionare un capacity provider):<\/p>\n\n\n\n

<\/p>\n\n\n\n

\"\"<\/figure>\n\n\n\n

<\/p>\n\n\n\n

Oggi abbiamo visto come adottare un approccio serverless per l’esecuzione delle pipeline GitLab, si tratta solo dell’inizio: ci sono molte altre strade da esplorare: container spot, build e deploy cross-account, architetture differenti (come ad esempio ARM e Windows).<\/p>\n\n\n\n

Avete gi\u00e0 provato ad ottimizzare le vostre build e pipeline? Fatecelo sapere nei commenti!<\/p>\n\n\n\n


\n\n\n\n

Resources:<\/p>\n\n\n\n