O blog da AWS
Migrando aplicações ASP.NET para containers, utilizando o AWS App2Container (A2C)
Por Márcio Morales, Arquiteto de Soluções em Tech Microsoft e
Caio Ribeiro César, Arquiteto de Soluções AWS Brasil
Todos os dias, as empresas estão executando aplicativos legados em arquiteturas de container altamente escalonáveis, como Amazon Elastic Container Service (ECS) e o Amazon Elastic Kubernetes Services (Amazon EKS). Isso ocorre porque os aplicativos legados, muitos deles baseados no Windows, podem ser difíceis de gerenciar e muitas vezes precisam de muita infraestrutura para mantê-los. Como muitos aplicativos legados não estão mais recebendo atualizações de software e são executados em sistemas operacionais que atingiram um ciclo de vida de fim de suporte, os clientes estão procurando uma nova maneira de reestruturar e gerenciar os ciclos de vida de aplicativos legados.
A Amazon Web Services lançou o AWS App2Container, um serviço que ajuda os clientes a criar containers de aplicativos legados sem fazer nenhuma alteração no código. Isso ajuda os clientes a executar aplicativos legados da Microsoft da mesma forma que executam novos aplicativos no Amazon ECS e no Amazon EKS. O AWS App2Container é um aplicativo cliente-servidor que analisa, extrai, coloca em containers e implementa aplicativos ASP.NET e JAVA no Amazon ECS ou Amazon EKS – tudo em apenas algumas etapas. Além disso, a AWS oferece suporte de produção para Kubernetes no Windows e oferece suporte total a nós de trabalho do Windows, tornando sua jornada de modernização perfeita.
Neste tutorial, colocamos em container um aplicativo ASP.NET chamado DNN Platform, que é um sistema de gerenciamento de conteúdo .NET de código aberto desenvolvido em ASP.NET e SQL Server. Para este tutorial, a camada de banco de dados da plataforma DNN foi migrada para o Amazon Relational Database Service (Amazon RDS).
Pré-Requisitos
Para este tutorial, você deve ter:
- Revisado todos os itens de pré-requisitos do App2Container.
- Executado uma instância do Amazon EC2 usando o Windows AMI otimizado para o Amazon ECS como a máquina de trabalho ou uma máquina virtual local com Docker instalado.
- Executado um cluster Amazon ECS baseado em Windows ou um cluster Amazon EKS com Windows Worker Nodes.
- Criado um bucket do Amazon S3 para armazenar artefatos gerados pelo App2Container.
Tutorial
Este tutorial possui os seguintes passos de execução:
- Criação de um usuário IAM e política para utilizar o AWS App2Container.
- Instalação do App2Container em um servidor.
- Inventário e análise da aplicação para migração.
- Extração da aplicação.
- Migrar a aplicação para container.
- Gerar os artefatos da aplicação para a migração.
- Executar a aplicação em um serviço gerenciado de container.
Passo 1: Criação de um usuário IAM e Política para utilizar o AWS App2Container.
- Crie um usuário IAM na AWS Command Line Interface executando o seguinte comando:
PowerShell New-IAMUser -Path "/ps-created-users/" -UserName "app2container"
b. Crie um arquivo JSON contendo a política IAM que corresponda ao Amazon EKS ou Amazon ECS, usando os exemplos na documentação oficial.
c. Crie a política IAM com base no arquivo JSON gerado na etapa e salve a saída do valor ARN a ser usada na próxima etapa.
PowerShell New-IAMPolicy -PolicyName "app2container" -policyDocument (Get-Content -Raw app2Container.json)
d. Anexe a política IAM recém-criada na etapa anterior ao usuário IAM recém-criado, executando o seguinte comando:
PowerShell Register-IAMUserPolicy -UserName app2container -PolicyArn arn:aws:iam::ID-DA-SUA-CONTA:policy/app2container
Passo 2: Instalação do App2Container em servidor remoto.
Este blog post original foi criado em Julho/2020. Desde então, temos novas versões e funcionalidades do App2Container. Uma destas funcionalidades é a possibilidade da execução do App2Container em um servidor remoto, utilizando o Shell Remoto do Windows (WinRM) e eliminando a necessidade de instalar o App2Container no servidor de aplicação.
Importante: Acesse este link para o procedimento de instalação do App2Container no modelo de acesso remoto.
O procedimento acima cobre os steps de ações necessárias no servidor em que o App2Container será instalado; o App2Container Workspace:
1/Set-ExecutionPolicy, 2/Criação de um AWS Secret que será utilizado na configuração, 3/Execução do comando “app2container remote inventory” para configurar o IP do servidor de aplicação e o secret de acesso.
Para o servidor de aplicação, temos:
1/Validação da porta de firewall 5986 para WinRM e 2/Execução do setup pelo WinRMSetup.ps1.
a. Assim que os passos acima forem executados, efetue o download do AWS App2Container e descompacte o conteúdo no servidor.
b. Execute o install.ps1 em uma sessão elevada do PowerShell para instalar o AWS App2Container.
c. Configure a ferramenta AWS App2Container usando seu usuário e política IAM recém-criado e configurado via aws cli (aws configure) e o seu bucket S3 com o seguinte comando:
app2container init
Pronto! O AWS App2Container está configurado e pronto para ser usado neste servidor.
Passo 3: Inventário e análise da aplicação para migração.
a. Agora iremos executar o comando remoto da máquina do App2Container para o servidor de aplicação:
app2container remote inventory --target ServidordeAplicação_IP/NomeDNS
Nesta etapa, todos os sites do IIS que podem ser modernizados para container pela ferramenta são exibidos. É importante observar que o AWS App2Container gerou um UID (por exemplo: iis-dnn-c5654c20) por aplicativo, que pode ser localizado no arquivo “inventory.json”. O UID é usado por todas as próximas etapas e tem um papel essencial na distinção de cada aplicativo.
{ "iis-default-web-site-a444e5c46d62": { "siteName": "Default Web Site", "bindings": "http/*:80:", "applicationType": "iis", "discoveredWebApps": [] }, "iis-dnn-5510d5ca0b2b": { "siteName": "dnn", "bindings": "http/*:80:", "applicationType": "iis", "discoveredWebApps": [] } }
b. Utilizando o UID gerado na sua execução, analise o aplicativo executando o seguinte comando:
app2container remote analyze –application-id APP-UID –target IP/NomeDNS
Nesta execução, o comando de análise App2Container gera um arquivo de análise chamado analysis.json. O relatório fornece a análise, bem como opções para atualizar os parâmetros utilizados para o processo de modernização para containers.
Compreender este arquivo de análise é uma etapa crucial de todo o processo. Vamos analisar!
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SectionForS3Access",
"Action": [
"s3:DeleteObject",
"s3:GetBucketAcl",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:GetObjectAcl",
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:PutObject",
"s3:PutObjectAcl"
],
"Effect": "Allow",
"Resource": "<user-provided-bucket-ARN>"
},
{
"Sid": "SectionForS3ReadAccess",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketAcl"
],
"Resource": "arn:aws:s3:::*"
},
{
"Sid": "SectionForECRAccess",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:BatchDeleteImage",
"ecr:BatchGetImage",
"ecr:CompleteLayerUpload",
"ecr:CreateRepository",
"ecr:DeleteRepository",
"ecr:DescribeImages",
"ecr:DescribeRepositories",
"ecr:GetAuthorizationToken",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:InitiateLayerUpload",
"ecr:ListImages",
"ecr:PutImage",
"ecr:TagResource",
"ecr:UntagResource",
"ecr:UploadLayerPart"
],
"Effect": "Allow",
"Resource": "<resource-ARNs>"
},
{
"Sid": "SectionForECSWriteAccess",
"Action": [
"ecs:CreateCluster",
"ecs:CreateService",
"ecs:CreateTaskSet",
"ecs:DeleteCluster",
"ecs:DeleteService",
"ecs:DeleteTaskSet",
"ecs:DeregisterTaskDefinition",
"ecs:Poll",
"ecs:RegisterContainerInstance",
"ecs:RegisterTaskDefinition",
"ecs:RunTask",
"ecs:StartTask",
"ecs:StopTask",
"ecs:SubmitContainerStateChange",
"ecs:SubmitTaskStateChange",
"ecs:UpdateContainerInstancesState",
"ecs:UpdateService",
"ecs:UpdateServicePrimaryTaskSet",
"ecs:UpdateTaskSet"
],
"Effect": "Allow",
"Resource": "<resource-ARNs>"
},
{
"Sid": "SectionForPassRoleToECS",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "<ARN for ecsTaskExecutionRole>"
},
{
"Sid": "SectionForECSReadAccess",
"Action": [
"ecs:DescribeClusters",
"ecs:DescribeContainerInstances",
"ecs:DescribeServices",
"ecs:DescribeTaskDefinition",
"ecs:DescribeTaskSets",
"ecs:DescribeTasks",
"ecs:ListClusters",
"ecs:ListContainerInstances",
"ecs:ListServices",
"ecs:ListTaskDefinitionFamilies",
"ecs:ListTaskDefinitions",
"ecs:ListTasks"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Sid": "SectionForCodeCommitAccess",
"Effect": "Allow",
"Action": [
"codecommit:GetRepository",
"codecommit:GetBranch",
"codecommit:CreateRepository",
"codecommit:CreateCommit",
"codecommit:TagResource"
],
"Resource": "arn:aws:codecommit:*:*:*"
},
{
"Sid": "SectionForByoVPC",
"Effect": "Allow",
"Action": [
"ec2:DescribeInternetGateways",
"ec2:DescribeRouteTables",
"ec2:DescribeSubnets",
"ec2:DescribeVpcs"
],
"Resource": "*"
},
{
"Sid": "SectionForEC2",
"Effect": "Allow",
"Action": [
"ec2:DescribeKeyPairs",
"ec2:CreateKeyPair",
"ec2:DescribeAvailabilityZones"
],
"Resource": "*"
},
{
"Sid": "SectionForMetricsService",
"Effect": "Allow",
"Action": "execute-api:invoke",
"Resource": "arn:aws:execute-api:us-east-1:*:*/prod/POST/put-metric-data"
},
{
"Sid": "SectionForUploadSupportBundleService",
"Effect": "Allow",
"Action": "execute-api:invoke",
"Resource": "arn:aws:execute-api:us-east-1:*:*/prod/POST/put-log-data"
},
{
"Sid": "SectionForSecretManagerAccess",
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Effect": "Allow",
"Resource": "arn:aws:secretsmanager:<user's region>:<user's account ID>:secret:a2c/*"
}
]
}
- O atributo “containerBaseImage” é a imagem base do Windows selecionada no Microsoft Container Registry. Você tem a opção de alterá-la e usar sua imagem base do Windows personalizada. É importante ressaltar que a imagem base do Windows deve corresponder à mesma versão do Windows no cluster Amazon ECS e/ou Amazon EKS.
- O atributo “imageRepositoryName” é o nome do Amazon ECR (Elastic Container Repository) que é criado para armazenar a imagem do container gerada pelo AWS App2Container. Você pode alterá-lo para um repositório existente ou alterar o nome se desejar.
- O atributo “imageTag” é a TAG criada na imagem do container.
- A opção “includeWebApplications” pode ser modificada caso você queira incluir sites IIS adicionais que podem fazer parte de seu aplicativo da web.
- O atributo “additionalExposedPorts” é uma opção para publicar portas adicionais ao invés da porta 80 (http) para o container.
- A opção “appIncludeFiles” serve para incluir todos os arquivos que não fazem parte do site IIS, como por exemplo, um arquivo DLL.
Este arquivo de análise produz a versão do Windows Server, a configuração do IIS e do pool de aplicativos, bindings, caminhos de arquivo e recursos instalados no Windows Server além do IIS e o caminho do arquivo report.txt. Este arquivo contém o nome do arquivo e o número da linha onde você pode alterar os strings de conexão do seu banco de dados.
Passo 4. Extração da aplicação
Execute o comando de “extração”. Ele contém todos os arquivos necessários para construir a imagem do container.
app2container remote extract --application-id –target IP/NomeDNS APP-UID
Passo 5. Migrar a aplicação para container.
Criar o Dockerfile do zero não é uma tarefa simples. Você precisa escrever Dockerfiles usando multi-stage para minimizar o número de camadas e entrypoints. O AWS App2Container simplifica este processo de construção da imagem do container, gerando um Dockerfile completo.
a. No Workspace em que iremos gerar o Dockerfile, conforme explicamos nos pré-requisitos, estamos utilizando uma Amazon ECS-optimized AMI. Esta instância (servidor remoto em que instalamos o App2Container) possui o DockerMsftProvider instalado e com o serviço iniciado.
Executamos então o comando abaixo:
app2Container containerize --input-archive C:\Users\Administrator\AppData\Local\app2container\remote\192.168.5.17\iis-dnn-5510d5ca0b2b\iis-dnn-5510d5ca0b2b.zip
b. Acesse o diretório do espaço de trabalho para ver a seguinte estrutura de diretórios / arquivos:
c. Selecione o diretório “Artifacts”, que é o diretório que o App2Container usa para construir a imagem do container.
Observação: o diretório “DNN” é o nome do site IIS que contém todos os arquivos de aplicativos da web.
- Dockerfile: é o Dockerfile gerado pelo AWS App2Container com base na configuração atual do IIS, e pode ser editado conforme necessário.
- ps1: é o ponto de entrada que será usado para enviar os registros do IIS para o Docker console.
- Podemos usar o msi para restaurar as configurações completas do IIS do ambiente de produção atual para usá-lo na imagem do Windows Container.
- WIN-KU.zip é o backup do IIS gerado pelo AWS App2Container e é usado com o WebDeploy no caso de uma restauração da configuração do IIS na imagem do container do Windows.
Agora, vamos examinar o arquivo Dockerfile gerado pelo AWS App2Container.
# escape= `
FROM mcr.microsoft.com/dotnet/framework/aspnet:4.7.2-windowsservercore-ltsc2019
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
RUN Remove-Website 'Default Web Site';
# Set up Website: dnn
RUN New-Item -Path 'C:\inetpub\dnn' -Type Directory -Force;
RUN if(-NOT (Get-IISAppPool 'dnn')) {New-WebAppPool -Name 'dnn' }
RUN New-Website -Name 'dnn' -PhysicalPath 'C:\inetpub\dnn' -Port 80 -ApplicationPool 'dnn' -Force;
COPY "dnn" "C:\inetpub\dnn"
RUN $path='C:\inetpub\dnn'; `
$acl = Get-Acl $path; `
$newOwner = [System.Security.Principal.NTAccount]('BUILTIN\IIS_IUSRS'); `
$acl.SetOwner($newOwner); `
dir -r $path | Set-Acl -aclobject $acl
EXPOSE 80
# Windows Authentication was not detected. Please Uncomment the below RUN commands if you want to use Windows Authentication."
# AppPool's Identity is set as Network Service to enable Windows Authentication using GMSA.
# RUN Install-WindowsFeature -Name Web-Windows-Auth -IncludeAllSubFeature
# RUN Import-Module WebAdministration; Set-ItemProperty 'IIS:\AppPools\dnn' -name processModel.identityType -value 2
# RUN Import-Module WebAdministration; Set-WebConfigurationProperty -Filter '/system.webServer/security/authentication/anonymousAuthentication' -Name Enabled -Value False -PSPath 'IIS:\' -Location 'dnn'
# RUN Import-Module WebAdministration; Set-WebConfigurationProperty -Filter '/system.webServer/security/authentication/windowsAuthentication' -Name Enabled -Value True -PSPath 'IIS:\' -Location 'dnn'
# Included files:
# Export additional ports
# Set up log volumes if needed, for example:
# VOLUME C:\inetpub\logs
# VOLUME C:\yourApp\App_Data\Logs
# The following Windows features are installed on your host, but not in the container.
# You can uncomment the ones you want to have them installed while building docker image.
# RUN Install-WindowsFeature -Name File-Services -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name FS-FileServer -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Web-Mgmt-Tools -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Web-Mgmt-Console -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name NET-Framework-Features -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name NET-Framework-Core -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name InkAndHandwritingServices -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Server-Media-Foundation -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name FS-SMB1 -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name User-Interfaces-Infra -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Server-Gui-Mgmt-Infra -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Desktop-Experience -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name Server-Gui-Shell -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name PowerShell-V2 -IncludeAllSubFeature
# RUN Install-WindowsFeature -Name PowerShell-ISE -IncludeAllSubFeature
# Uncomment the following section will restore your server configuration in your container.
# COPY 'WIN-7RTMG2CCH7P_WebServer_20210310193928.zip' 'C:\temp\WIN-7RTMG2CCH7P_WebServer_20210310193928.zip'
# COPY 'WebDeploy_amd64_en-US.msi' 'C:\temp\WebDeploy_amd64_en-US.msi'
# RUN Start-Process 'C:\temp\WebDeploy_amd64_en-US.msi' '/qn' -PassThru | Wait-Process
# RUN Add-PSSnapin 'WDeploySnapin3.0' ; Restore-WDServer -Package 'C:\temp\WIN-7RTMG2CCH7P_WebServer_20210310193928.zip'
No Dockerfile, podemos ver que o App2Container seleciona a imagem base do aplicativo ASP.NET no arquivo analysis.json. No entanto, podemos editar a imagem base conforme necessário. Ao fazer isso, temos que nos certificar de que a nova imagem corresponda à versão do Container Host OS.
Windows Containers não são domain-joined. Para utilizar a autenticação do Windows em um container do Windows requer o uso de gMSA e algumas alterações de autenticação no IIS (veja as notas para ECS e para EKS). O AWS App2Container prepara a imagem do container para oferecer suporte à autenticação do Windows adicionando as seguintes configurações no Dockerfile:
- Alteração da conta do IIS Application Pool para utilizar a conta de serviço de network (Network Service Account).
- Intalação da feature de IIS para autenticação Windows
- Alteração da autenticação IIS para desabilitar a autenticação anônima e habilitar a autenticação Windows.
O App2Container também fornece dois scripts PowerShell como saídas para o comando “app2container containerize”, junto com um arquivo de instrução. O primeiro script do PowerShell DomainJoinAddToSecGroup.ps1 ingressa no host do container e o adiciona a um grupo de segurança do Active Directory. O segundo script CreateCredSpecFile.ps1 cria o gMSA, concede acesso ao grupo de segurança do AD para recuperar a senha gMSA e gera o arquivo Docker credspec.
Passo 6. Gerar os artefatos da aplicação para a migração.
a. Por padrão, o AWS App2Container gera os artefatos a serem usados no Amazon ECS, mas você pode alterá-lo para gerar artefatos a serem usados no Amazon EKS.
Abra o arquivo deployment.json gerado pelo app2container.
Veja que existem alguns parâmetros de configuração. Entre eles, dois parâmetros:
- createECSArtifacts: true
- createEKSArtifacts: false
Se modificarmos o valor de createEKSArtifacts para “true” e o valor de createEcsArtifcats para “false”, o app2container irá gerar os artefatos para o Amazon EKS ao invés do Amazon ECS.
b. Para gerar os artefatos de aplicativos a serem usados com o Amazon ECS ou o Amazon EKS, execute o comando abaixo (como pré-requisito, o bucket de S3 deve ter sido configurado na etapa de app2container init).
app2container generate app-deployment --application-id APP-UI
c. Agora, podemos ver os seguintes arquivos:
- EksDeployment Directory contém um modelo CloudFormation para a implementação do cluster EKS e Windows nodes.
- O yaml é o arquivo de manifesto que podemos utilizar para a implementação do Windows Pod no Amazon Elastic Kubernetes Services (Amazon EKS).
- Oyaml é o arquivo de manifesto que podemos utilizar para a implementação do serviço Kubernetes no Amazon Elastic Kubernetes (Amazon EKS).
- Ojson é o arquivo de manifesto que podemos utilizar para a implementação do pipeline CI / CD a ser usado junto com o cluster Amazon ECS/Amazon EKS.
Passo 7. Executar a aplicação em um serviço gerenciado de container.
Conforme discutido anteriormente, no laboratório utilizado para este blog post, escolhemos o serviço de Amazon Kubernetes Service (EKS). Nada impede neste cenário que a modernização da nossa aplicação ocorra no Amazon Elastic Container Service (ECS). Para uma lista de funcionalidades de cada produto, clique aqui.
kubectl apply -f eks_service.yaml
kubectl apply -f eks_deployment.yaml
b. Confirme se o pod está funcionando. O status deve ser “1/1” em READY e “running” em STATUS.
kubectl get pod
c. Por meio do navegador da web, acesse o Elastic Load Balancer (ELB) criado pelo cluster Amazon EKS. Isso irá redirecionar para o pod onde podemos acessar a aplicação.
Pronto! Você acaba de migrar a sua aplicação ASP.NET para containers, utilizando o AWS App2Container (A2C).
Considerações
Statefulness: se a sua aplicação armazena estado na memória, a estrada para escalar em containers é um pouco mais árdua. Cada container possui sua própria condição e, consequentemente, cada request para a aplicação pode ter um comportamento diferente. Para resolver este problema, podemos utilizar proxies reversos com funcionalidades de sticky sessions, porém recomendamos a utilização de aplicações “stateless” para a sua modernização. Além de soluções da camada de networking, podemos melhorar o statefulness na camada de aplicação; para isso, utilizamos a integração do Session State com um banco de dados semi-estruturado (como DynamoDB) ou até soluções de caching (Elasticache).
Conclusão
Este processo nos permite unificar a infraestrutura necessária para operar seus aplicativos legados, ajudando a economizar em custos de infraestrutura e gerenciamento. Especificamente, o App2Container ajuda a armazenar esses aplicativos em containers e padronizá-los em um único conjunto de ferramentas para monitoramento, operações e entrega de software.
Para obter informações adicionais sobre como monitorar Amazon EKS Windows Pods, você pode ler esta postagem do blog da AWS. Para saber mais sobre a persistência de dados em containeres do Windows em execução no Amazon EKS, confira esta postagem do blog ou esta postagem do blog do Amazon ECS.
Para saber mais sobre como migrar o Windows Server ou SQL Server, visite o nosso site Windows na AWS. Para obter mais informações sobre como a AWS pode ajudá-lo a modernizar seus aplicativos herdados do Windows, verifique nossa página Modernização.
Caso possua interesse, entre em contato conosco para iniciar sua jornada de modernização ainda hoje.
Sobre o autor
Marcio Morales atualmente trabalha como arquiteto de soluções especializadas em tecnologia da Microsoft e atua como SME (Subject Matter Expert) para soluções com Windows container na plataforma AWS.
Caio Ribeiro Cesar atualmente trabalha como arquiteto de soluções especializadas em tecnologia da Microsoft na nuvem AWS. Ele iniciou sua carreira profissional como administrador de sistemas, que continuou por mais de 14 anos em áreas como Segurança da Informação, Identity Online e Plataformas de Email Corporativo. Recentemente, se tornou fã da computação em nuvem da AWS e auxilia os clientes a utilizar o poder da tecnologia da Microsoft na AWS.
Revisores
Enrico Bergamo é Arquiteto de Soluções especialista em Serverless na AWS para a América Latina, e atua auxiliando clientes de diversos segmentos em suas jornadas de modernização de aplicações na nuvem. Com mais de 10 anos de experiência em Arquitetura e Desenvolvimento de Sistemas, e DevOps, Enrico atuou diretamente com diversas empresas na definição, implementação, e implantação de diversas soluções corporativas.