O blog da AWS

Melhorar experiência de Desenvolvimento na AWS usando Jetbrains IntelliJ IDE

Por Diego Castro, Arquiteto de Infraestrutura em Nuvem na AWS e
Leonardo Lopes, Arquiteto de Infraestrutura em Nuvem na AWS

 

Este guia demonstra um padrão de arquitetura para permitir que os desenvolvedores acessem os recursos da AWS usando o Jetbrains IntelliJ IDE de maneira segura e eficiente e destina-se a arquitetos e desenvolvedores de soluções.

Este padrão se aplica a empresas que possuem uma ou mais das características abaixo:

  • Blocos de IP privados esgotados, levando a VPCs com intervalos de IP conflitantes (IP overlapping) com outras redes locais.
  • Proibido manter cópia local de código-fonte na estação de trabalho local.
  • Jetbrains IntelliJ é o IDE (Integrated Development Environment) de escolha para o desenvolvimento de aplicativos nativos na nuvem AWS.

Como resultado dessas características, os desenvolvedores não têm acesso direto aos recursos VPC, tornando o desenvolvimento um processo lento.

Neste blog post abordaremos o uso do AWS Systems Manager (SSM) junto com o Projector que é uma tecnologia desenvolvida pela JetBrains para acessar remotamente IDEs e aplicações Swing e mostraremos um template CloudFormation para automatizar o processo.

Pré-Requisitos

Arquitetura Proposta

Usando o AWS Systems Manager (SSM) em conjunto com o Projector é possível acessar uma instância de IntelliJ remota em uma instância EC2 usando cliente nativo do Projector ou via navegador web, sem a necessidade de exposição a Grupos de Segurança em subnets públicas.  Isso permite que os desenvolvedores estabeleçam conexões para uma instância de IntelliJ contida em sua VPC e aos recursos da AWS para o desenvolvimento de aplicativos na nuvem AWS.

Esse tipo de acesso fornece ao desenvolvedor experiência semelhante ao desenvolvimento conectado em seu VPC de desenvolvimento: permite acesso e resposta de desenvolvimento usando recursos da AWS e com as mesmas ferramentas de desenvolvimento com as quais estão familiarizados.

Enquanto resolve os tempos de resposta de desenvolvimento, permite uma gestão centralizada usando instância EC2 provisionada por meio de um template CloudFormation.

 

  1. A partir de sua estação de trabalho, o desenvolvedor requisita um redirecionamento de porta para o AWS Systems Manager usando AWS CLI.
  2. Usando o SSM Endpoint IP recebido, o SSM Plugin CLI interage com o AWS Systems Manager onde o redirecionamento de porta é executado.
  3. Usando o cliente nativo Projector, o desenvolvedor usará a instância EC2 implementada como ambiente de desenvolvimento remoto para acessar o IntelliJ, permitindo o acesso aos recursos VPC com experiência semelhante como se conectado localmente em sua VPC.

JetBrains IDE Remoto – Projector

Projector é uma tecnologia desenvolvida pela JetBrains, com licenciamento Open Source,  que executa IDEs baseados em IntelliJ e aplicativos baseados em Swing no servidor permitindo que você os acesse de qualquer lugar usando navegadores Web e cliente nativo. Você pode:

  • Acessar recursos não disponíveis localmente.
  • Manter governança corporativa sobre o ambiente de desenvolvimento.
  • Usar ferramentas não disponíveis em sua máquina local.
  • Acessar ambiente de desenvolvimento a partir de varios locais remotos.
  • Padronizar o ambiente de desenvolvimento.

Projector Home Page:

https://lp.jetbrains.com/projector/

Passo 1 – Implemente o CloudFormation stack

O CloudFormation cria um LaunchTemplate e uma instância EC2 e gera output para que seja feito o redirecionamento de porta via AWS Systems Manager. Características da instância EC2:

  • Última versão de Amazon Linux 2 (AMI lida via Parameter Store)
  • Tipos de instâncias propostas t3.medium, t3.large ou m5.large.
    • Default “t3.medium” e customizável via parâmetros do CloudFormation)
  • Volumes EBS GP3 dedicados e criptografado para projetos IntelliJ.
    • IOPS: 2000 IOPs (customizável via parâmetros do CloudFormation).
    • Throuhput: 125 Mib/s (customizável via parâmetros do CloudFormation).
  • Volume de Sistema Operacional criptografado.
  • Instalação de Python 3.8, Java 11 (Amazon Corretto) e bibliotecas necessárias ao Projector.
  • Instalação da última versão estável do Projector.
  • Criação de um serviço para manter o Projector em execução.
  • Configuração da IDE “IntelliJ IDEA Community Edition 2020.3.2”.

A seção de parâmetros requer:

  • SubnetID de uma subnet privada.
  • Grupo de segurança existente com acesso de saída HTTPS para o serviço AWS Systems Manager ou VPC Endpoints configurados.
    • Caso não tenha, pode criar um Grupo de Segurança usando a documentação de referência.
  • EC2 instance role que permite que a instância seja gerenciada pelo AWS Systems Manager.
    • Políticas necessárias: “AmazonSSMManagedInstanceCore”, “S3 Access https://docs.thinkwithwp.com/systems-manager/latest/userguide/ssm-agent-minimum-s3-permissions.html” e “CloudWatchAgentServerPolicy (opcional)”
  • O template CloudFormation fará o lookup automaticamente via AWS Systems Manager Parameter Store para o ID da AMI mais recente de Amazon Linux v2.
1.   AWSTemplateFormatVersion: 2010-09-09
2.   Description: CloudFormation template to automate EC2 creation for a remote IntelliJ instance
3.                
4.   Parameters:
5.    
6.     PrivateSubnetId:
7.       Description: Private Subnet Id to create the instance 
8.       Type: AWS::EC2::Subnet::Id
9.       Default: ""
10.  
11.   MySecGroup:
12.     Description: SecGroup for the Server
13.     Type: String
14.     Default: ""
15.  
16.   MyIamInstanceProfile:
17.     Description: IAM-EC2-Instance-Profile
18.     Type: String
19.     Default: ""
20.  
21.   LatestAmiId:
22.     Type: "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>"
23.     Default: "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
24.  
25.   InstanceTypeParameter:
26.     Type: String
27.     Default: t3.medium
28.     AllowedValues:
29.       - t3.medium
30.       - t3.large
31.       - m5.large
32.     Description: Enter t2.micro, t3.medium, t3.large or m5.large. Default is t3.medium.
33.   
34.   GP3Iops:
35.     Type: String
36.     Default: 2000
37.     Description: "Enter IOPs for the GP3 volumes in the range: 3,000-16,000 IOPS."
38.  
39.   GP3Throuhput:
40.     Type: String
41.     Default: 125
42.     Description: "Enter throuhput for the GP3 volumes: 125 to 1,000 MiB/s."
43.  
44.  
45. Resources:
46.  
47.   ProjectorLaunch:
48.     Type: AWS::EC2::LaunchTemplate
49.     Properties:
50.       LaunchTemplateData:
51.         BlockDeviceMappings: 
52.         - Ebs:
53.             VolumeSize: 100
54.             VolumeType: gp3
55.             Iops: !Ref GP3Iops
56.             Throughput: !Ref GP3Throuhput
57.             DeleteOnTermination: false
58.             Encrypted: true
59.           DeviceName: /dev/xvdcz
60.         - Ebs:
61.             VolumeSize: 30
62.             VolumeType: gp3
63.             Iops: !Ref GP3Iops
64.             Throughput: !Ref GP3Throuhput
65.             DeleteOnTermination: false
66.             Encrypted: true
67.           DeviceName: /dev/xvda
68.         Monitoring: 
69.           Enabled: true
70.         ImageId: !Ref LatestAmiId
71.         InstanceType: !Ref InstanceTypeParameter
72.         TagSpecifications:
73.         - ResourceType: instance
74.           Tags:
75.           - Key: Name
76.             Value: "IntelliJ"
77.  
78.   ProjectorEC2:
79.     Type: AWS::EC2::Instance
80.     Properties: 
81.       LaunchTemplate:
82.         LaunchTemplateId: !Ref ProjectorLaunch
83.         Version: !GetAtt ProjectorLaunch.LatestVersionNumber  
84.       SubnetId: !Ref PrivateSubnetId
85.       SecurityGroupIds:
86.         - !Ref MySecGroup
87.       IamInstanceProfile: !Ref MyIamInstanceProfile
88.       UserData:
89.         Fn::Base64: |
90.           #!/bin/bash
91.           pvcreate /dev/xvdcz
92.           vgcreate vgproj /dev/xvdcz
93.           lvcreate -l 100%FREE -n lvproj vgproj
94.           mkfs.ext4 /dev/vgproj/lvproj
95.           sudo -u ec2-user mkdir -p /home/ec2-user/projector
96.           echo "/dev/mapper/vgproj-lvproj /home/ec2-user/projector ext4 defaults 0 2" >> /etc/fstab
97.           mount -a
98.           chown ec2-user:ec2-user /home/ec2-user/projector
99.           #Basic packages for OS, Projector and convenience
100.             yum update -y 
101.             yum groupinstall 'Development Tools' -y
102.             yum install -y amazon-linux-extras
103.             amazon-linux-extras enable python3.8
104.             yum install python38 wget unzip less libXext libXrender libXtst libXi freetype \
105.                   git bash-completion procps amazon-efs-utils amazon-linux-extras \
106.                   python38-devel java-11-amazon-corretto libxkbcommon libXcomposite libXdamage \
107.                   libXfixes libgbm libatspi atk-devel pango-devel cups-devel at-spi2-core \
108.                   alsa-lib atk pyOpenSSL python-cryptography libXtst -y
109.             python3.8 -m pip install --upgrade pip
110.             python3.8 -m pip install python-dev-tools
111.             printf '\nPATH=$PATH:"/usr/local/bin/"\nexport PATH\n' >> ~/.bashrc
112.             printf '\nPATH=$PATH:"/usr/local/bin/"\nexport PATH\n' >> ~/home/ec2-user/.bashrc
113.             python3.8 -m pip install projector-installer
114.             #Projector Profile specifics
115.             configname=$(wget -q -O - http://169.254.169.254/latest/meta-data/instance-id)
116.             #idename matches the community version used by itau
117.             idename="IntelliJ IDEA Community Edition 2020.3.2"
118.             #portnumber is the listener the specific projector profile will work on
119.             portnumber='7777'
120.             installPath=/usr/local/bin/projector
121.             projectorDir=/home/ec2-user/projector
122.             user=ec2-user
123.             #create data dirs
124.             sudo -u $user mkdir -p $projectorDir/apps
125.             sudo -u $user mkdir -p $projectorDir/cache
126.             sudo -u $user mkdir -p $projectorDir/configs
127.             chown $user:$user $projectorDir/apps
128.             chown $user:$user $projectorDir/cache
129.             chown $user:$user $projectorDir/configs   
130.             #Projector profile creation
131.             sudo -u $user $installPath --accept-license --config-directory $projectorDir --cache-directory $projectorDir autoinstall --config-name $configname --ide-name "$idename" --port $portnumber 
132.             sudo -u $user $installPath --config-directory $projectorDir --cache-directory $projectorDir install-certificate $configname
133.             echo "Service Creation"
134.             cat << EOF > /etc/systemd/system/IntelliJ.service
135.             [Unit]
136.             Description=Jetbrains Projector
137.             After=network.target nss-lookup.target
138.             Wants=network-online.target
139.             [Service]
140.             Type=simple
141.             User=ec2-user
142.             ExecStart=/home/ec2-user/projector/configs/$configname/run.sh
143.             Restart=always
144.             RestartSec=5
145.             StartLimitIntervalSec=0
146.             [Install]
147.             WantedBy=multi-user.target
148.             EOF
149.             systemctl start IntelliJ
150.             systemctl enable IntelliJ
151.             echo "End of UserData"
152.    
153.   Outputs:
154.     ProjectorEC2ID:
155.       Description: EC2 ID
156.       Value: !Ref ProjectorEC2
157.     SSMPortFWCommand:
158.       Description: SSM PortFW Cmd
159.       Value: !Join
160.               - ''
161.               - - 'aws ssm start-session --target '
162.                 - !Ref ProjectorEC2
163.                 - ' --document-name AWS-StartPortForwardingSession --parameters'
164.                 - ' localPortNumber=8888,portNumber=7777'
165.                 - ' --profile profile-name'

Passo 2 – Usando AWS CLI realize autenticação em sua conta

Caso necessite de assistência para realizar autenticação via AWS CLI, por favor verifique instruções em:  https://docs.thinkwithwp.com/cli/latest/userguide/cli-chap-configure.html

Passo 3 – Faça o redirecionamento de porta usando o SSM Plugin para AWS CLI

Acesse a console do CloudFormation e lá encontre o comando para realizar o redirecionamento de porta. O comando é uma saída gerada pelo CloudFormation stack com o nome de chave “SSMPortFWCommand”:

Altere “profile-name” com o nome do seu profile nomeado ou remova o parâmetro caso esteja usando um profile default via AWS CLI.

A porta local “tcp 8888” será redirecionada para a porta “tcp 7777” na instância EC2 criada na AWS, porta a qual o Projector está sendo executado.

Passo 4 – Projector Launcher

Use o cliente nativo, também conhecido como “Projector Launcher” ou um Web Browser para acessar a configuração IDE IntelliJ remota usando o endereço https://localhost:8888 .

 

Acesse recursos da VPC usando o IDE IntelliJ remoto:

 

 

No exemplo mostrado pode-se verificar acesso aos recursos AWS a partir da instância remota via IntelliJ.

É possível customização e instalação de plugins no IntelliJ e aplicar políticas de governança, segurança e patching.

Conclusão

Um ambiente governando para o desenvolvimento de aplicações nativas em nuvem é o que muitas corporações estão buscando. A combinação do AWS Systems Manager e o Projector permite uma completa gestão deste ambiente e sem a necessidade de exposição à tráfego de entrada a partir da Internet em Grupos de Segurança. Também permite acesso aos recursos AWS em ambientes segmentados onde ocorra conflitos de blocos de endereçamento IP entre redes corporativas e o ambiente AWS.

Nesse post, nós mostramos o uso do AWS CloudFormation para automatizar a criação de uma instância EC2 para ser usada como ambiente de desenvolvimento Jetbrains IntelliJ e para gerar o comando de redirecionamento de porta via AWS Systems Manager, além de configurar o serviço Projector na instância EC2 remota.

 


Sobre os autores

Diego Castro é Arquiteto de Infraestrutura na AWS Brasil. Com 21 anos de experiência tem grande interesse por automação, infraestrutura como código, containers e cultura DevOps.

 

 

 

 

Leonardo Lopes é Arquiteto de Infraestrutura na AWS Brasil. Com mais de 20 anos de experiência em infraestrutura e arquitetura em ambientes de alta disponibilidade e performance.