Este post está dedicado a proveer instrucciones detalladas acerca de la manera en la que se debe crear una infraestructura de integración continua usando herramientas como GitLab, Jenkins, Nexus, Sonar, Swagger editor, Rancher, H2 y Keycloak. Todo lo anterior sobre AWS, pero con la asociación de nombres de dominio adecuados (subdominios) y su correspondiente SSL.

Requisitos básicos

A lo largo de este post se hará uso extensivo de conceptos, herramientas y tecnologías muy particulares que son enumeradas a continuación:

  1. Cuenta de un “Registar” como GoDaddy o Akky
  2. Cuenta AWS con privilegios para EC2 y Route53
  3. Cuenta con algún proveedor de certificados SSL
  4. Nuestra estación de trabajo deberá tener instalado el cliente de consola de aws también conocido como awscli y deberá estar configurado para que las credenciales de acceso estén creadas y disponibles para su uso

Esto último, aws cli, es posible que sea instalado en Ubuntu (probado en la versión 18.04) simplemente ejecutando el comando:

sudo apt install awscli

Posteriormente, se debreá configurar el cliente con las crdenciales requeridas. esto se puede hacer mediante:

aws configure

Durante la configuración se pedirán los siguientes datos:

  1. AWS Access Key ID
  2. AWS Secret Access Key ID
  3. Región (Yo uso: “us-east-1”)
  4. Formato (ENTER = FORMATO POR DEFAULT)

NOTA IMPORTANTE: Los valores de (1) y (2) son generados por un administrador de AWS, mediante el uso de la interfaz gráfica de AWS en la sección de seguridad. Son únicos y son revocables en cualquier momento. Sin estos datos será muy complejo continuar con este Tutorial. Es extremadamente recomendable obtenerlos en este punto antes de continuar con esta lectura.

Pasos previos a la creación de la Infraestructura

Antes de poder generar la Infraestructura de integración continua será necesario gestionar los siguiente:

I Compra de dominio

Un “Registrar” es una compañía (como GoDaddy o como Akky) que vende nombres de dominio que se encuentren disponibles. Generalmente es posible comprar un dominio “.com” o un dominio “.org” disponible por unos 10 dólares al año o menos. Hay dominios mas caros, como los dominios “.io” o los dominios “.tv” que cuestan unos 50 dólares al año.

Los dominios con nombres cortos ya han sido comprados y si se desea negociar su transferencia o venta, ésta puede llegar a costar miles de dólares. Un ejemplo es “Tesla” que fue vendido al fabricante de autos eléctricos por 75,000 dólares.

Una vez que el dominio ha sido adquirido, el “Registrar” enviará al comprador una serie de datos e instrucciones al correo que éste último indicó al momento del registro o compra del dominio. La operación completa toma al rededor de 10 minutos.

Es MUY recomendable que el correo que se indica para la compra del dominio en cuestión sea un correo dedicado para sólo este fin. En este sentido, conviene crear un correo gratuito (gmail, outlook, hotmail, yahoo o cualquier otro) y usarlo sólo para este propósito. De esta manera, si algún día decidimos vender el dominio, la transferencia será mucho mas fácil y directa.

Nota importante

II Creación de una Zona en AWS Route53

AWS Ofrece una interfaz para la gestión de dominios, sub dominios y registros A, AAA, CNAME, TXT, etc de los nombes de dominio que hayamos adquirido con un registrar. Esto es posible a través de la interfaz llamada Route53.

En el momento en el que damos de alta en Route53 un nombre de dominio que hayamos adquirido con algún “Registrar”, podremos observar que se generan cuatro cadenas de texto asociadas a los “name servers” (servidores de nombre) que AWS crea de manera automática. Se deberá tomar nota de esas cuatro cadenas ya que serán usadas en el siguiente paso.

III Alta de Name Servers en el “Registrar”

Con la información generada por AWS Route53 en referencia a las 4 cadenas de texto asociadas a los “Name Servers”, se deberá ingresar a la interfaz del “Registrar” y solicitar la redirección de los DNS’s que tiene (generalmente apuntados a servidores de nombre de si mismo) pero ahora ingresando la nueva información.

En un siguiente paso se verificará que si esto se hizo correctamente, ya que no es posible hacerlo de manera inmediata, pues este cambio generalmente toma una o dos horas en hacerse efectivo.

Mientras tanto, se deberán realizar otras actividades que se explican a continuación.

IV Generación de una IP estática, permanente y homologada

Durante este proceso, será requerida una única IP estática y homologada que será nuestra puerta de acceso a todos los servicios de nuestra infraestructura de integración continua.

La generación de una IP homologada es posible ya sea gracias a la interfaz de EC2 que provee AWS en la sección de “Elastic IP” o bien mediante la ejecución de un sencillo script para aws cli:

aws ec2 allocate-address \
    --domain vpc \
    --network-border-group us-east-1

Que nos genera la siguiente respuesta de EJEMPLO:

{
    "PublicIp": "70.224.234.241",
    "AllocationId": "eipalloc-02463d08ceEXAMPLE",
    "PublicIpv4Pool": "amazon",
    "NetworkBorderGroup": "us-east-1",
    "Domain": "vpc"
}

Evidentemente, esta respuesta será diferente cada vez que el primer comando sea invocado. El dato que nos interesa es el IP generado. En este ejemplo es “70.224.234.241”. Se deberá tomar nota de tal IP ya que será empleado en el siguiente paso.

También es MUY importante anotar el “AllocationId” asociado a esta IP, ya que será requerido al momento de asignar esta IP a una instancia de EC2, cosa que haremos hacia el final de este tutorial.

V Generación de subdominios

La generación de subdominios se realiza en la interfaz de Route53 que provee AWS y básicamente requiere de cuatro datos:

  1. Nombre del subdominio (es el conjunto de segmentos que van al inicio de nuestro nombre de dominio, como www, ftp o estructuras mas compplejas como srv01.ci, uno.dos.tres, etc)
  2. Tipo de registro, que en nuestro caso será siempre “A”, salvo un único caso que se discutirá próximamente (registro TXT)
  3. Dirección IP, que en nuestro caso es la IP estática, homologada generada en el punto IV
  4. TTL que es un número y en nuestro caso siempre será: 60 (“Time To live” representa el número de segundos de refresco)

También es posible usar el cliente consola de AWS para dar de alta tales subdominios. Si se desea realizar de esta forma, l referencia puede ser consultada en esta liga: https://docs.aws.amazon.com/cli/latest/reference/route53/index.html

Por otro lado, “en caso” de que se tenga la posibilidad de usar el sdk de aws, entonces la generación de varios dominios se puede “automatizar” con el siguiente segmento de código java que contiene sólo dos métodos:

    
    public CreateZoneSubdomains(String hostedZoneId, String domain, String ip) {
        String dns = Tools.getScriptTextPlain("zone-names.txt");
        String[] names = dns.split(" ");
        changeRecordSetTypeA(hostedZoneId, domain, ip);
        for(String name : names) {
            if(name.trim().length()>0) {
                changeRecordSetTypeA(hostedZoneId, name.trim() + ".ci."+domain, ip);
            }
        }
    }

    public ChangeResourceRecordSetsResult changeRecordSetTypeA(
            String hostedZoneId, String subdomain, String ip) {
        @SuppressWarnings("deprecation")
        AmazonRoute53Client route53Client = new AmazonRoute53Client();
   
        GetHostedZoneResult hostedZoneResult = route53Client.getHostedZone(
            new GetHostedZoneRequest(hostedZoneId));
        HostedZone hostedZone = hostedZoneResult.getHostedZone();
    
        ResourceRecordSet resourceRecordSet = new ResourceRecordSet()
            .withName(subdomain)
            .withType(RRType.A)
            .withTTL(60L)
            .withResourceRecords(new ResourceRecord().withValue(ip));
    
        ChangeResourceRecordSetsRequest request = new ChangeResourceRecordSetsRequest()
            .withHostedZoneId(hostedZone.getId())
            .withChangeBatch(new ChangeBatch()
                    .withChanges(new Change()
                            .withAction(ChangeAction.CREATE)
                            .withResourceRecordSet(resourceRecordSet)
                     )
             );
        Tools.prn("Se ha creado el subdominio: [%s] en el ip: [%s]\n", subdomain, ip);
        return route53Client.changeResourceRecordSets(request);
     }

VI Solicitud de certificados SSL

Con la información de propiedad de nombre de dominio es posible realizar la compra de certificados SSL. Para este caso, será INDISPENSABLE solicitar un certificado de tipo WILDCARD. Esto nos permitirá usarlo en cualquier subdominio del dominio asociado. Es recomendable que se pida del tipo “green”. Estos certificados, después de pagados los podemos empezar a usar de manera inmediata. El proceso completo de compra y descarga, posterior a la compra no toma mas de 10 minutos y los proveedores que ofrecen estos servicios son variados: Verisign, Commodo, CheapSSL, etc. Un certificado WILDCARD “green” de Verisign puede costar unos 50 usd al año, aproximadamente.

Próximamente tales certificados serán requeridos en la configuración del servidor Nginx, ya que habrá que indicar su trayectoria en un apartado similar al siguiente:

ssl_certificate     /some/path/fullchain.pem;
ssl_certificate_key /some/path/privkey.pem;

fullchain.pem is a concatenation of cert.pem and chain.pem in one file. In most servers you’ll specify this file as the certificate, so the entire chain will be send at once.

Fuente: Super Goose

En caso de que en un futuro se desee emplear otro servidor web, como Apache, por ejemplo, quizá sea necesario generar mas archivos asociados al SSL y si el vendedor no los generó ni envió de manera previa, la herramienta (libre) openssl quizá nos podría ser de utilidad para tal efecto.

En el momento de solicitar la generación de los archivos asociados al certificado SSL, es posible que el proveedor de certificados (por ejemplo, Verisign) nos pida crear un registro TXT en Route53. Sería un procedimiento prácticamente igual al que hicimos para la creación manual de subdominios en Route53, pero en vez de usar “A” sería “TXT”.

VII Creación del servidor de “Front”

En esta sección se creará un servidor EC2 al cual le asignaremos en su momento, la IP estática que nos entregó AWS y que responderá (via un servidor nginx) adecuadamente ante cada petición de nombre de dominio hacia tal IP.

Para este efecto, se requerirá de tener los siguientes recursos ya creados:

  1. Grupo de seguridad con puertos abiertos: 22, 80, 443, 1521, 5005 para el CIDR: 0.0.0.0./0
  2. Grupo de seguridad con puertos abiertos: 0-65535 para el CIDR: 171.31.0.0/16
  3. Keypair de acceso ssh para el servidor de Front (vale la pena crear este recurso en la interfaz de EC2)
  4. La IP estática y homologada generada en pasos previos (requeriremos el “id” asociado a esta IP. Si no lo anotamos cuando se creó, podemos recuperarlo en la interfaz de EC2)
  5. Archivo de Pre-Configuración e instalación de Software inicial.

Se recuerda que todas las operaciones, configuraciones y ajustes descritos en este documento, pueden ser gestionados directamente desde la interfaz de AWS, pero que también es posible usar la interfaz de linea de comandos “aws cli” para el mismo efecto. Dicho lo anterior, para la mayoría de solicitudes se mostrará el código asociado a ejecutar desde la interfaz de comandos “aws cli”.

El siguiente código nos permite crear un grupo de seguridad con las carecterísticas que se mencionan en párragos anteriores:

aws ec2 create-security-group \
--group-name my-sg-any-name \
--description "My security group description" \
--vpc-id vpc-4b8d0531

Obtendremos la siguiente respuesta:

{
    "GroupId": "sg-0824778f9d1e68ac1"
}

Con el “ID” obtenido, podremos agregar “reglas” a tal grupo. En este caso, la regla es la apertura del rango de puertos del 3389 al 4123, que serán accesibles sólo desde el rango de IP’s 172.31.0.0/16

aws ec2 authorize-security-group-ingress \
--group-id sg-0824778f9d1e68ac1 \
--protocol tcp \
--port 3389-4123 \
--cidr 172.31.0.0/16

Con 256×256 direcciones capacez de conectar con ese rango de puertos de la vpc existente de la región. El rango de IP’s fué calculado usando la herramienta en la siguiente liga: http://www.subnet-calculator.com/cidr.php

La bandera “–port” soporta un rango de puertos (como el que se usó) o un simple número, como 22, por ejemplo.

En este punto se deberá crear un “Keypair” y la mejor manera de hacer esto es via la interfaz de EC2. Para este ejemplo, el nombre del “Keypair” será “frontKey”

Nota importante !!!

Para crear una instancia de EC2, se deberá usar este código:

aws ec2 run-instances \
--image-id ami-085925f297f89fce1 \
--count 1 \
--instance-type t2.small \
--key-name frontKey \
--security-group-ids sg-058aa6ea0649c0f92 \
--user-data file://script_00.txt \
--block-device-mappings "[{\"DeviceName\":\"/dev/sda1\",\"Ebs\":{\"VolumeSize\":20,\"DeleteOnTermination\":false}}]"

Con lo anterior, se solicita la creación de una (–count=1) instancia de EC2 de Ubuntu 18_04 (ami-085925f297f89fce1), con 1 CPU y 2 Gigas de memoria RAM (t2.small), 20 Gb de disco SSD, con llave de acceso “frontKey”, en elgrupo de seguridad dado (sg-058aa6ea0649c0f92) y ejecutando la serie de comandos descritos en el archivo “script_00.txt”

El contenido del archivo “script_00.txt” es el siguiente:

#!/bin/bash

sh -c "echo 'LC_ALL=en_US.UTF-8\\nLANG=en_US.UTF-8' >> /etc/environment"

apt update
apt install -y docker-ce
apt install -y docker-compose
apt install -y s3fs
apt install -y sshfs

gpasswd -a ubuntu docker

mkdir -p /home/ubuntu/{.ssh,services,shared-s3,shared-ssh}
echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDjybz2kqMxcryhVVOCRWPlBt9//gDTcQECrleQZyO2F1diR+7ANZ7iHFB1+ZdDRv6qi45aL7EaNDAtIxAJp4IxSYAiQeycdUfoiTX/HYkQWj5+13Zc0Rw+SARFJ9KnRZM8Al2olEOfqnCUxBkTj24sozfeSViAi+CfzANL/TlS1lfvbF/icbRgDqvXeqqqdOMxFf6rWYJG5nqIirfa6EpOWjsEnjLSWAyZCfuV/A6wk0fosSBQnzs/K6f8aSe2AZtDX7RRYQELeW7i2J2KS9DqpptMRRD1ysRBKp9qxqS7SKBEFVOMsUVLHRPbJcpdDc0SHLu7j/7sv3JGXJPyja2b" >> /home/ubuntu/.ssh/authorized_keys

wget --no-check-certificate 'https://cutt.ly/gzvViBW' -O /home/ubuntu/bridge.tar.gz

tar xzvf /home/ubuntu/bridge.tar.gz -C /home/ubuntu
chown -R ubuntu:ubuntu /home/ubuntu timedatectl set-timezone America/Mexico_City

Una vez que la instancia de EC2 está en estado operacional, se deberá asignar la IP estática homologada a tal instancia. Como siempre, esto puede ser realizado via la interfaz gráfica de AWS en la sección de EC2 (elastic IP) o bien via la ejecución del siguiente comando:

aws ec2 associate-address \
--instance-id i-0b263919b6498b123 \
--allocation-id eipalloc-64d5890a

Con lo anterior, hemos asociado el “id” de una dirección ip estática al “id” de una instancia EC2.

En este punto, ya es posible usar la llave privada de “frontKey” que generamos en la interfaz gráfica de AWS (módulo EC2) para acceder al servidor de front con la ip estática que acabamos de asociar y hasta lo podemos hecer con alguno de los nombres de dominio que hemos asociado a esa IP al inicio de este Tutorial. La forma de acceder se la siguiente:

ssh -i frontKey.pem -o "StrictHostKeyChecking no" ubuntu@server.com.mx

Una vez dentro…

1. correr el script de search & replace para el nombre del dominio
2. colocar los certificados en una ruta adecuada
3. correr el script para la generación del keystore de java
4. correr el script de arranque de Nginx
5. verificar que se llega a los dominios indicados

listo !!!! To be continue…

Sorry, the comment form is closed at this time.

© 2020 Goose Workshop Suffusion theme by Sayontan Sinha