people
By: Marlon Mantilla
APPS
15 August 2017
people
15 August 2017
APPS
By: Marlon Mantilla

Como lanzar una aplicación estática en Amazon S3 con Bitbucket Pipelines

Amazon S3, Bitbucket

En estos días tuve la oportunidad de utilizar Bitbucket Pipelines por primera vez y me gustó tanto que dejaré aquí los pasos para lanzar una aplicación estática a Amazon S3 usando Bibucket Pipelines.

Ahora se preguntarán el porque debo usar bitbucket pipelines, pues bueno de esta forma podrás configurar continuous Integration/Delivery de una manera sencilla y rápida. En pocas palabras podrás probar y desplegar aplicaciones a producción dependiendo de la estrategia que escojas. En el ejemplo que veremos a continuación tendremos un servidor de pruebas (staging) y un servidor de producción.

Cuando subamos código al branch development harémos deploy a nuestro servidor de pruebas. Usualmente este servidor es donde nuestro equipo de QA (Quality assurance) verifica que todo funcione correctamente y una vez aprobado los cambios subiremos a producción, en nuestro caso simplemente mezclando los cambios en el branch master.

Configurando Amazon S3

Para este ejemplo haré deploy de este site, es un ejemplo sencillo pero en realidad puede ser cualquier sitio estático, una app de Angular, React, etc.

No iremos paso a paso en como crear un bucket en S3, pero hay algo muy importante que es habilitar la opción Static website hosting en las propiedades del bucket. De esta forma ya estará configurado tu site como sitio estático en S3.

screenshot

Una vez tengamos el bucket pueden subir manualmente los archivos para verificar que todo funcione correcto. Para este ejemplo esta será nuestra página web.

Configurando Bitbucket Pipelines

Habilitar pipelines en tu proyecto es muy sencillo, simplemente en el menu de tu proyecto en Bitbucket ve a Pipelines y presiona el botón Commit file al archivo de ejemplo.

screenshot

Esto lo que hará es agregar el archivo bitbucket-pipelines.yml al root de su repositorio. Una vez tenemos este archivo en nuestro repositorio, bitbucket da por hecho la activación de pipelines. En ese archivo es donde vamos a configurar nuestros builds, donde cada build será un deploy a producción o staging (servidor de pruebas).

En este ejemplo no estamos teniendo en cuenta tests, pero suponiendo que configuren un CI/CD también pueden agregar sus tests automatizados a cada build.

Nuestro archivo bitbucket-pipelines.yml esta en formato YAML, en él podremos definir nuestros pipelines. Paso seguido nos encargamos de definir que va a suceder en cada uno de nuestros builds, piensen esto como un recipe o una lista de comandos a ejecutar cada vez que hacen push al repositorio. Bitbucket tomará la configuración de este archivo y creará un Docker container donde ejecutará los comandos que nosotros definamos.

Para subir nuestro site en Amazon S3, nuestro archivo bitbucket-pipelines.yml deberá lucir así:

# bitbucket-pipelines.yml
image: attensee/s3_website

pipelines:
  branches:
    master:
      - step:
          script:
            - s3_website push --config-dir config/production
    development:
      - step:
          script:
            - s3_website push --config-dir config/sandbox

image Te permite especificar la imágen de Docker a usar, si no se especifica todo se ejecutará con la imágen predeterminada de Bitbucket. Para facilitar subir los archivos al bucket vamos a usar la gema s3_website que sirve para administrar un bucket de Amazon S3.

¿Qué es Docker?: para hacerte una idea es un software que permite correr procesos en contenedores, puedes pensar que es como una maquina virtual pero portable y mucho más ligera. Para más información puedes entrar aquí.

pipelines En esta sección es donde definimos el flujo de cada build, puedes definir paso a paso por branches o por tags. En nuestro caso vamos a definir pipelines por branches, el branch master para producción y el branch development para staging.

step es donde se define que se va a ejecutar por cada build.

script en donde especificamos los pasos a ejecutar en el build. A cada paso se le antepone un -. En este ejemplo tenemos un sólo paso a ejecutar y es s3_website push --config-dir config/sandbox para el caso del branch development.

Agregando variables de entorno en Bitbucket

Para subir los archivos al bucket necesitamos las credenciales de Amazon (Access Key ID, Secret Access Key) que las puedes generar desde tu consola de amazon en Security Credentials. Por motivos de seguridad estas llaves no pueden estar en el repositorio, pero Bitbucket tiene una forma segura de almacenarlas y es con Environment variables.

Para agregar una variable de entorno puedes hacerlo en el Menu Settings - Environment variables:

screenshot

Importante para mayor seguridad activa el checkbox de Secured al momento de crear la variable de esta forma no se verán explicitos cuando se ejecuten los builds ni tampoco podrán verla directamente otros usuarios al editar.

Para nuestro ejemplo vamos a crear las siguientes variables:

  • AWS_KEY: access key de Amazon.
  • AWS_SECRET: secret key de Amazon.
  • PRODUCTION_BUCKET: El nombre del S3 bucket para producción.
  • SANDBOX_BUCKET: El nombre del S3 bucket para pruebas.

Creando archivo de configuración para s3_website

El comando s3_website push necesita de un archivo llamado s3_website.yml en donde se especifican los valores de las credenciales de Amazon, recuerden son necesarias para obtener los permisos para subir archivos a un bucket.

Volviendo a nuestros pasos del pipeline de development:

- step:
    script:
      - s3_website push --config-dir config/sandbox

El comando s3_website viene con un task llamado push, este task se encargará de subir archivos al bucket con las especificaciones del archivo s3_website.yml, en este caso el directorio cambia dependiendo del branch y lo especificamos con: --config-dir. De esta forma cada vez que se haga un push al branch development se van a subir los archivos con las especificaciones de config/sandbox/s3_website.yml.

Vamos a crear un folder llamado config y dentro de este un folder sandbox para el servidor de pruebas y otro folder production para el servidor de producción. Para este ejemplo así es como se ven mis archivos:

*html-test
  - config
     -- production
       --- s3_website.yml
     -- sandbox
       --- s3_website.yml
  - site
    .... SITIO WEB ...
  bitbucket-pipelines.yml

Finalmente así es como quedan los archivos de configuración para cada branch:

# config/sandbox/s3_website.yml
s3_id: <%= ENV['AWS_KEY'] %>
s3_secret: <%= ENV['AWS_SECRET'] %>
s3_bucket: <%= ENV['SANDBOX_BUCKET'] %>
site: ../../site
# config/production/s3_website.yml
s3_id: <%= ENV['AWS_KEY'] %>
s3_secret: <%= ENV['AWS_SECRET'] %>
s3_bucket: <%= ENV['PRODUCTION_BUCKET'] %>
site: ../../site

Últimos pasos

Finalmente si todo está bien configurado, pueden hacer una prueba haciendo push al branch development. Si se van a Bitbucket en la sección de Pipelines así es como debería verse:

screenshot

Si algo sale mal verán el estado failed y si le dan click encima del estado podrán ver las razones del porque falló. Del mismo modo si hacen push al branch master deberán ver un build nuevo en Pipelines.

Si entran a su bucket podrán ver su website, en mi caso:

Conclusión

Bitbucket pipelines es una buena opción para configurar deploys automatizados de páginas web estáticas, recuerden esto mismo lo pueden aplicar para una aplicación hecha en Angular, React, Ember o lo que se les ocurra (bueno que sea una aplicación estática HTML/CSS/Javascript).

En cuanto a costos $$$, siempre y cuando los builds no excedan los 50 minutos mensuales Bitbucket NO te cobrará nada! (al ser una aplicación estática los builds son muy rápidos), lo que me parece genial.