Solución:
He creado un conjunto de archivos de muestra para acompañar la guía que se proporciona a continuación. Estos archivos están disponibles en el siguiente enlace: https://gitlab.com/autronix/gitlabci-ec2-deployment-samples-guide/
Alcance
Esta guía asume lo siguiente
- Proyecto alojado en Gitlab EE: puede funcionar en instancias privadas de CE / EE (no probado)
- Gitlab como repositorio de versiones de GIT
- Gitlab-CI como motor de integración continua
- Cuenta de AWS existente
- AWS EC2 como sistema de preparación o producción de destino para la implementación
- Instancia de AWS EC2 que ejecuta la AMI de Amazon Linux
- AWS S3 como instalación de almacenamiento para archivos de implementación
- AWS CodeDeploy como motor de implementación del proyecto
- AWS CodePipeline como canalización para la implementación
El proporcionado .gitlab-ci.yml
La muestra se basa en un proyecto Java / Scala + Gradle. El script se proporciona como un ejemplo genérico y deberá adaptarse a sus necesidades específicas al implementar Continuous Delivery a través de este método.
La guía asumirá que el usuario tiene conocimientos básicos sobre los servicios de AWS y cómo realizar las tareas necesarias.
Nota: La guía proporcionada en este ejemplo utiliza la consola de AWS para realizar tareas. Si bien es probable que existan equivalentes de CLI para las tareas que se realizan aquí, no se tratarán en toda la guía.
Motivación
La motivación para crear estos scripts y la guía de implementación provino de la falta de disponibilidad de un tutorial adecuado que muestre cómo implementar Continuous Delivery utilizando Gitlab y AWS EC2. Gitlab introdujo su motor de CI de libre acceso al asociarse con Digital Ocean, que permite que los repositorios de usuarios se beneficien de la CI de buena calidad de forma gratuita.
Una de las principales ventajas de usar Gitlab es que proporcionan contenedores de integración continua incorporados para ejecutar los distintos pasos y validar una compilación. Desafortunadamente, Gitblab ni AWS proporcionan una integración que permitiría realizar la entrega continua después de las compilaciones pasadas.
Esta guía y los scripts (https://gitlab.com/autronix/gitlabci-ec2-deployment-samples-guide/) proporcionan una versión simplificada de los pasos que he realizado para tener un IC y un CD exitosos utilizando Gitlab y AWS EC2 que puede ayudar a cualquier otra persona a comenzar con este tipo de implementación.
Configuración del entorno en AWS
El primer paso para garantizar un proceso de entrega continua exitoso es configurar los objetos necesarios en AWS para permitir que el proceso de implementación sea exitoso.
Usuario de AWS IAM
El requisito inicial será configurar un usuario de IAM:
https://console.aws.amazon.com/iam/home#users
- Crea un usuario
-
Adjunte los siguientes permisos:
- CodePipelineFullAccess
- AmazonEC2FullAccess
- AmazonS3FullAccess
- AWSCodeDeployFullAccess
-
Política en línea:
"Version": "2012-10-17", "Statement": [ "Effect": "Allow", "Action": [ "autoscaling:*", "codedeploy:*", "ec2:*", "elasticloadbalancing:*", "iam:AddRoleToInstanceProfile", "iam:CreateInstanceProfile", "iam:CreateRole", "iam:DeleteInstanceProfile", "iam:DeleteRole", "iam:DeleteRolePolicy", "iam:GetInstanceProfile", "iam:GetRole", "iam:GetRolePolicy", "iam:ListInstanceProfilesForRole", "iam:ListRolePolicies", "iam:ListRoles", "iam:PassRole", "iam:PutRolePolicy", "iam:RemoveRoleFromInstanceProfile", "s3:*" ], "Resource": "*" ]
-
Genera credenciales de seguridad
Nota: Las políticas enumeradas anteriormente tienen un alcance muy amplio. Puede ajustarse a sus requisitos creando políticas personalizadas que limiten el acceso solo a ciertos recursos.
Nota: Guarde estas credenciales en un lugar seguro. Los necesitará en un paso posterior.
Instancia y rol de AWS EC2
Rol de instancia para CodeDeploy
https://console.aws.amazon.com/iam/home#roles
Cree un nuevo rol que se asignará a su instancia EC2 para acceder a S3,
- Establezca el nombre de acuerdo con sus convenciones de nomenclatura (es decir.
MyDeploymentAppRole
) - Seleccione
Amazon EC2
para permitir que las instancias EC2 ejecuten otros servicios de AWS - Adjunte las siguientes políticas:
- AmazonEC2FullAccess
- AmazonS3FullAccess
- AWSCodeDeployRole
Nota: Las políticas enumeradas anteriormente tienen un alcance muy amplio. Puede ajustarse a sus requisitos creando políticas personalizadas que limiten el acceso solo a ciertos recursos.
Lanzamiento de instancia
https://console.aws.amazon.com/ec2/v2/home
Haga clic en Launch Instance
y sigue estos pasos:
- Seleccione
Amazon Linux AMI 2016.03.3 (HVM), SSD Volume Type
- Seleccione el tipo de instancia requerido (t2.micro por defecto)
- próximo
- Seleccione
IAM Role
serMyDeploymentAppRole
(basado en el nombre creado en la sección anterior)- próximo
- Seleccione el almacenamiento apropiado
- próximo
- Etiquete su instancia con un nombre apropiado (p. Ej.
MyApp-Production-Instance
)- agregue etiquetas adicionales según sea necesario
- próximo
- Configure el grupo de seguridad según sea necesario
- próximo
- Revisa y lanza tu instancia
Se le proporcionará la posibilidad de generar o utilizar claves SSH. Seleccione el método correspondiente correspondiente.
Configurar el entorno de la instancia
Instalar el agente de CodeDeploy
Inicie sesión en su instancia EC2 recién creada y siga las instrucciones:
- http://docs.aws.amazon.com/codedeploy/latest/userguide/how-to-run-agent-install.html
CodeDeploy rutas importantes:
- Directorio base de implementación de CodeDeploy:
/opt/codedeploy-agent/deployment-root/
- Archivo de registro de CodeDeploy:
/var/log/aws/codedeploy-agent/codedeploy-agent.log
Propina: correr tail -f /var/log/aws/codedeploy-agent/codedeploy-agent.log
para realizar un seguimiento del despliegue en tiempo real.
Instale los requisitos previos de su proyecto
Si su proyecto tiene requisitos previos para ejecutarse, asegúrese de instalarlos antes de ejecutar la implementación; de lo contrario, su secuencia de comandos de inicio puede fallar.
Repositorio de AWS S3
https://console.aws.amazon.com/s3/home
En este paso, deberá crear un depósito de S3 que contendrá sus archivos de implementación.
Simplemente siga estos pasos:
- Escoger
Create Bucket
- Seleccione un nombre de depósito (p. Ej.
my-app-codepipeline-deployment
) - Seleccione una región
- Seleccione un nombre de depósito (p. Ej.
- En la consola de su balde, seleccione
Properties
- Ampliar la
Versioning
menú - escoger
Enable Versioning
- Ampliar la
AWS CodeDeploy
https://console.aws.amazon.com/codedeploy/home#/applications
Ahora que los elementos básicos están configurados, estamos listos para crear la aplicación de implementación en CodeDeploy.
Para crear una aplicación de implementación de CodeDeploy, siga estos pasos:
- Seleccione
Create New Application
- Elija un nombre de aplicación (es decir.
MyApp-Production
) - Elija un nombre de grupo de implementación (es decir.
MyApp-Production-Fleet
) - Seleccione las instancias EC2 que se verán afectadas por esta implementación:
Search by Tags
- Debajo
Key
SeleccioneName
- Debajo
Value
SeleccioneMyApp-Production-Instance
- Debajo
- Debajo
Service Role
, SeleccioneMyDeploymentAppRole
- Haga clic en
Create Application
Nota: Puede asignar la implementación a cualquier etiqueta relevante que se haya aplicado a las instancias deseadas destinadas a la implementación. En aras de la simplicidad, solo se ha utilizado la etiqueta de nombre para elegir la instancia previamente definida.
AWS CodePipeline
https://console.aws.amazon.com/codepipeline/home#/dashboard
El siguiente paso es continuar con la creación de CodePipeline, que se encarga de realizar la conexión entre el bucket de S3 y el proceso de CodeDeploy.
Para crear una CodePipeline, siga estos pasos:
- Haga clic en
Create Pipeline
- Nombra tu canalización (es decir.
MyAppDeploymentPipeline
)- próximo
- Selecciona el
Source Provider
paraAmazon S3
- colocar
Amazon S3 location
a la dirección de su depósito y archivo de implementación de destino (es decir.s3://my-app-codepipeline-deployment/myapp.zip
) - próximo
- colocar
- Colocar
Build Provider
paraNone
– Esto ya lo maneja Gitlab-CI, como se tratará más adelante.- próximo
- Colocar
Deployment Provider
paraAWS CodeDeploy
- colocar
Application Name
al nombre de su aplicación CodeDeploy (es decir.MyApp-Production
) - colocar
Deployment Group
al nombre de su grupo de implementación de CodeDeploy (es decir.MyApp-Production-Fleet
) - próximo
- colocar
- Crear o elegir un rol de servicio de canalización
- próximo
- Revise y haga clic
Create Pipeline
Configurando el entorno en Gitlab
Ahora que el entorno de AWS se ha preparado para recibir la implementación de la aplicación, podemos continuar con la configuración del entorno y la configuración de CI para garantizar que el código se compile y se implemente en una instancia EC2 utilizando S3, CodeDeploy y CodePipeline.
Variables de Gitlab
Para que la implementación funcione, necesitaremos establecer algunas variables de entorno en el repositorio del proyecto.
En su proyecto de Gitlab, navegue hasta el Variables
área para su proyecto y establezca las siguientes variables:
AWS_DEFAULT_REGION
=> su región de AWSAWS_SECRET_ACCESS_KEY
=> su clave secreta de credenciales de usuario de AWS (obtenida cuando generó las credenciales para el usuario)AWS_ACCESS_KEY_ID
=> su ID de clave de credencial de usuario de AWS (obtenido cuando generó las credenciales para el usuario)AWS_S3_LOCATION
=> la ubicación de su archivo zip de implementación (es decir.s3://my-app-codepipeline-deployment/my_app.zip
)
Estas variables serán accesibles por los scripts ejecutados por los contenedores Gitlab-CI.
Script de inicio
Se ha proporcionado una secuencia de comandos de inicio simple (https://gitlab.com/autronix/gitlabci-ec2-deployment-samples-guide/blob/master/deploy/extras/my_app.sh) para permitir que la implementación realice las siguientes tareas:
- Inicie la aplicación y cree un archivo PID
- Verifique el estado de la aplicación a través del archivo PID
- Detener la aplicación
Puede encontrar este script en deploy/extras/my_app.sh
Creando gitlab-ci.yml
los gitlab-ci.yml
file se encarga de realizar las tareas de Integración Continua asociadas con una determinada confirmación. Actúa como un grupo simplificado de scripts de shell que se organizan en etapas que corresponden a las diferentes fases de los pasos de integración continua.
Para obtener más información sobre los detalles y la referencia, consulte los dos enlaces siguientes:
- http://docs.gitlab.com/ce/ci/quick_start/README.html
- http://docs.gitlab.com/ce/ci/yaml/README.html
Puede validar la sintaxis de su gitlab-ci.yml
archivo en cualquier momento con la siguiente herramienta: https://gitlab.com/ci/lint
Para el propósito de la implementación, cubriremos solo la última parte del ejemplo que se proporciona con esta guía:
deploy-job:
# Script to run for deploying application to AWS
script:
- apt-get --quiet install --yes python-pip # AWS CLI requires python-pip, python is installed by default
- pip install -U pip # pip update
- pip install awscli # AWS CLI installation
- $G build -x test -x distTar # # Build the project with Gradle
- $G distZip # creates distribution zip for deployment
- aws s3 cp $BUNDLE_SRC $AWS_S3_LOCATION # Uploads the zipfile to S3 and expects the AWS Code Pipeline/Code Deploy to pick up
# requires previous CI stages to succeed in order to execute
when: on_success
stage: deploy
environment: production
cache:
key: "$CI_BUILD_NAME/$CI_BUILD_REF_NAME"
untracked: true
paths:
- build/
# Applies only to tags matching the regex: ie: v1.0.0-My-App-Release
only:
- /^vd+.d+.d+-.*$/
except:
- branches
- triggers
Esta parte representa todo el trabajo asociado con la implementación que sigue a las etapas de CI anteriores, si las hay.
La parte relevante asociada con la implementación es esta:
# Script to run for deploying application to AWS
script:
- apt-get --quiet install --yes python-pip # AWS CLI requires python-pip, python is installed by default
- pip install -U pip # pip update
- pip install awscli # AWS CLI installation
- $G build -x test -x distTar # # Build the project with Gradle
- $G distZip # creates distribution zip for deployment
- aws s3 cp $BUNDLE_SRC $AWS_S3_LOCATION # Uploads the zipfile to S3 and expects the AWS Code Pipeline/Code Deploy to pick up
El primer paso consiste en instalar el sistema de administración de paquetes de Python: pip
.
pip
es necesario para instalar AWS CLI, que es necesario para cargar el archivo de implementación en AWS S3
En este ejemplo, estamos usando Gradle (definido por la variable de entorno $G
); Gradle proporciona un módulo para comprimir automáticamente los archivos de implementación. Dependiendo del tipo de proyecto que esté implementando, este método será diferente para generar el archivo zip de distribución. my_app.zip
.
los aws s3 cp $BUNDLE_SRC $AWS_S3_LOCATION
El comando carga el archivo zip de distribución en la ubicación de Amazon S3 que definimos anteriormente. Luego, CodePipeline detecta automáticamente este archivo, lo procesa y lo envía a CodeDeploy. Finalmente, CodeDeploy realiza las tareas necesarias a través del agente de CodeDeploy según lo especificado por el appspec.yml
expediente.
Creando appspec.yml
los appspec.yml
define el comportamiento que debe seguir CodeDeploy una vez que se recibe un archivo de implementación.
Se ha proporcionado un archivo de muestra junto con esta guía junto con scripts de muestra que se ejecutarán durante las diversas fases de la implementación.
Consulte la especificación de CodeDeploy AppSpec para obtener más información sobre cómo construir el appspec.yml
archivo: http://docs.aws.amazon.com/codedeploy/latest/userguide/app-spec-ref.html
Generación del archivo zip de implementación
Para que CodeDeploy funcione correctamente, debe crear un archivo zip generado correctamente de su aplicación.
El archivo zip debe contener:
- Raíz de cremallera
appspec.yml
=> Instrucciones de implementación de CodeDeploy- scripts de la etapa de implementación
- siempre que las muestras se coloquen en el
scripts
directorio en el archivo zip, requeriría la presenciamy_app.sh
script que se agregará en la raíz del directorio de su aplicación (es decir.my_app
directorio en el zip) - código de distribución – en nuestro ejemplo estaría bajo el
my_app
directorio
Herramientas como Gradle y Maven son capaces de generar archivos zip de distribución con ciertas alteraciones en el proceso de generación de zip. Si no usa dicha herramienta, es posible que deba indicarle a Gitlab-CI que genere este archivo zip de una manera diferente; este método está fuera del alcance de esta guía.
Implementar su aplicación en EC2
El último paso de esta guía es realizar una implementación exitosa.
Las etapas de Integración Continua están definidas por las reglas establecidas en el gitlab-ci.yml
. El ejemplo proporcionado con esta guía iniciará una implementación para cualquier referencia que coincida con la siguiente expresión regular: /^vd+.d+.d+-.*$/
.
En este caso, presionar una etiqueta v1.0.0-My-App-Alpha-Release
a través de git en su Gitlab remoto iniciaría el proceso de implementación. Puede ajustar estas reglas según corresponda a los requisitos de su proyecto.
los gitlab-ci.yml
El ejemplo proporcionado realizaría los siguientes trabajos al detectar la etiqueta v1.0.0-My-App-Alpha-Release
:
- construir trabajo – compilar las fuentes
- trabajo de prueba: ejecuta las pruebas unitarias
- deploy-job: compile las fuentes, genere el zip de distribución, cargue el zip en Amazon S3
Una vez que se ha cargado el zip de distribución en Amazon S3, se llevan a cabo los siguientes pasos:
- CodePipeline detecta el cambio en la revisión del archivo zip S3
- CodePipeline valida el archivo
- CodePipeline envía una señal de que el paquete de CodeDeploy está listo
- CodeDeploy ejecuta los pasos de implementación
- Inicio: inicialización de la implementación
- Detención de la aplicación: ejecuta un script definido para el gancho.
- DownloadBundle: obtiene el archivo del paquete del repositorio de S3 a través de CodePipeline
- BeforeInstall: ejecuta el script definido para el gancho
- Instalar: copia el contenido en la ubicación de implementación según lo definido por el
files
Sección deappspec.yml
- AfterInstall: ejecuta un script definido para el gancho
- ApplicationStart: ejecuta un script definido para el gancho
- ValidateService: ejecuta un script definido para el gancho
- Fin: indica a CodePipeline que la implementación se ha completado correctamente.
Capturas de pantalla de implementación exitosa:
Referencias
- Inicio rápido de Gitlab-CI: http://docs.gitlab.com/ce/ci/quick_start/README.html
- Gitlab-CI .gitlab-ci.yml: http://docs.gitlab.com/ce/ci/yaml/README.html
- Tutorial de AWS CodePipeline: http://docs.aws.amazon.com/codepipeline/latest/userguide/getting-started-w.html
- Instale o reinstale el agente de AWS CodeDeploy: http://docs.aws.amazon.com/codedeploy/latest/userguide/how-to-run-agent-install.html
- Introducción a la AWS CLI – Env: http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-environment
- Referencia de AppSpec: http://docs.aws.amazon.com/codedeploy/latest/userguide/app-spec-ref.html