lunes, 17 de febrero de 2014

AWS: Building blocks

AWS es principalmente conocido por sus máquinas virtuales, servicio formalmente conocido como EC2 (Elastic Cloud Computing). Pero AWS ofrece mucho mas. El set de servicios es extenso y crece cada día. En una serie de entradas en este blog me gustaría enseñar algunos de ellos partiendo de los mas simples y comunes hasta los mas complejos. El objetivo es obtener una visión general de lo que AWS puede ofrecernos desde una aproximación práctica y amena.

Pero dejemos de hablar y pongámonos manos a la obra. Primero necesitaremos establecer un entorno adecuado donde desplegar nuestra arquitectura. Partamos de un diseño de arquitectura tradicional con dos redes diferenciadas: una de frontend donde desplegaremos los servicios de cara al publico y otra de backend donde instalaremos los servicios de bases de datos. Esquemáticamente:

Diagrama general

Los elementos principales que deberemos definir son:

  • VPC (Virtual Private Cloud): Es el espacio reservado para nosotros donde desplegaremos toda la infraestructura. Piensa en ello como un trozo de AWS donde podrás definir todo lo que necesiten tus servicios. Usaremos para nuestra VPC un rango 10.0.0.0/16 que nos dará un amplio margen de direccionamiento.
  • Internet Gateway: Será nuestra punto de conexión entre la VPC e Internet
  • Public subnet: La subred pública. Con un rango de 10.0.0.0/24 pondremos dentro de esta subred todas las máquinas que ofrecerán servicio de cara al público (frontend)
  • Private subnet: La red privada. En esta subred contendrá todas las máquinas con información privada. Su acceso estará mas limitado y generalmente se utilizan para contener la información (backend)
  • NAT Instance: Las máquinas de backend por seguridad no deben conectarse directamente a Internet. Pero generalmente necesitarán hacer conexiones al exterior, por ejemplo para actualizar paquetes. La instancia de NAT nos permitirá poder hacer estas comunicaciones desde el backend de forma mas segura. 
  • Web Server: El servidor web que ofrecerá los servicios a nuestros clientes. 
  • DB Server: El servidor de base de datos que contendrá la información que use nuestro aplicativo.
Veamos cómo podemos crear y configurar este entorno de forma rápida y sencilla en AWS.

NOTA: Crear recursos en tu cuenta AWS puede tener asociado costes. Si no estas seguro consulta la tabla de precios para cada servicio antes de iniciar cualquier cambio que pueda derivar en un sobrecoste mensual inesperado.


Creación de la red y subredes

Creación de la VPC

Entramos en la consola AWS y seleccionamos el servicio VPC. En 'Your VPCs' nos aparecerán todas las VPC que tenemos creada para la región actual. Pulsamos el botón 'Create VPC' e introducimos los datos:


Una vez pulsado el botón 'Yes, Create' nos aparecerá nuestra nueva VPC dentro de la lista de VPCs disponibles:



Ahora nos vamos al apartado 'Subnets' y pulsamos el botón 'Create Subnet'. Deberemos repetir el proceso dos veces, una por cada subred que queremos crear:




Una vez hecho, nos deberán aparecer las dos nuevas subredes en la lista de subredes disponibles para la región:



Por último en el apartado de redes deberemos crear un Internet Gateway. Para hacerlo, nos vamos al apartado 'Internet Gateways' y pulsamos el botón 'Create Internet Gateway'. Ahora, pulsando botón derecho del ratón sobre el Internet Gateway que acabamos de crear, seleccionamos 'Attach to VPC' para asociarlo a nuestra VPC 10.0.0.0/16:


Una vez hecho, en la lista aparecerá asociado el Internet Gateway a la VPC:




Instancia NAT

NAT son las siglas de Network Address Translation y es un mecanismo usado por los routers para encaminar paquetes entre diferentes redes. Si recordais, tenemos dos subredes diferentes: una con los servidores de producción o frontend y otra con los servidores que contienen la información o backend. Por seguridad crearemos una instancia de NAT que colocaremos en la subred de frontend con dos funciones principales:
  1. Punto único de entrada para la administración: Habilitaremos reglas para poder acceder a esta instancia a tréves del puerto SSH (22/TCP) con el objetivo de administrar el entorno. Crear un único punto de entrada nos securizará el entorno y nos permitirá mas fácilmente controlar el acceso. En el resto de instancias nos ocuparemos de securizarlas para permitir solo accesos de administración desde la instancia de NAT y abrir los puertos de servicio requerido para clientes o internos, según el caso.
  2. Puente de comunicación para la red de backend: No es seguro que la red de backend se comunique directamente con Internet, pero puede que sea necesario para algunas labores como la actualización de paquetes por ejemplo. Para restringir este tráfico configuraremos para que el tráfico de las instancias de esta subred sea enrutado por la instancia de NAT.
Lo primero que necesitaremos será crear esta instancia de NAT. Amazon ya provee de una AMI enfocada a este propósito. En nuestra consola AWS iremos al servicio EC2 --> Instances y pulsaremos el botón 'Launch Instance'. En '1. Choose AMI' iremos a 'Community AMIs', marcaremos la casilla 'Amazon Linux' del apartado 'Operating System' y en el campo de búsqueda escribiremos 'NAT':




Seleccionaremos la AMI de fecha mas reciente. En '2. Choose Instance Type' elegiremos una t1.micro ya que el propósito de este artículo es demostrativo. Para un entorno productivo real deberíamos elegir un tipo de instancia adecuado al throughput de red que necesitemos.


Seguimos. En '3. Configure Instance' en los apartados 'Network' y 'Subnet' seleccionaremos la VPC 10.0.0.0/16 y la subred 10.0.0.0/24. De esta forma enmarcamos la instancia dentro de la subred de frontend:


Next, en '4. Add Storage' lo dejaremos por defecto. Esta instancia no necesita de almacenamiento adicional. Con el volumen raíz será suficiente. Siguiente, en '5. Tag Instance' como nombre le asignaremos el valor 'NAT instance'. De esta forma reconoceremos facilmente la instancia posteriormente. En '6. Configure Security Group' configuraremos un nuevo grupo de seguridad llamado 'NAT-Security-Group' y, por ahora, permitiremos el acceso SSH desde cualquier origen. Esto es inseguro y es altamente recomendable modificarlo para restringir el conjunto de IPs que puedan acceder a este puerto. Pero por ahora, y para facilitar la configuración, lo dejaremos así:


En el último apartado, '7. Review', revisaremos las opciones elegidas y si estamos conforme pulsaremos el botón 'Launch' para crear la nueva instancia:


Después de unos segundos nuestra nueva instancia NAT aparecerá disponible en la lista de instancias en ejecución para la región seleccionada.

Dado que nuestra instancia NAT necesitará comunicarse con Internet necesitará disponer de una IP pública. Para conseguirlo haremos uso de las EIP, Elastic IP. En la consola AWS iremos al servicio VPC, apartado 'Elastic IPs' y pulsaremos al botón 'Allocate New Address'. Una vez creada la IP pública pulsando sobre ella con el botón derecho del razón seleccionamos 'Associate' y la asociaremos a la instancia de NAT:



Con esto, ya tenemos una IP pública asociada a la instancia de NAT. En la consola AWS, vamos a EC2 --> Instances. En el apartado 'Security Groups' seleccionaremos el grupo de seguridad de nuestra instancia NAT y añadiremos una regla de entrada (Inbound) para permitir todo el tráfico desde la red VPC (10.0.0.0/16):


Esto permitirá a las máquinas de nuestra VPC comunicarse a través de la instancia de NAT. Podremos restringir esto mas adelante (de hecho es lo recomendable para aumentar la seguridad), pero por ahora lo dejaremos así. Solo resta deshabitar el chequeo de ip origen y destino en la instancia. Volvemos a EC2 --> Instances , botón derecho sobre la instancia NAT y seleccionamos 'Change Source/Dest. Check' para poner el valor a 'False':


Por defecto las instancias AWS tienen este chequeo activo por motivos de seguridad, denegando cualquier paquete en el que no aparezca la IP de la instancia como origen o destino. Pero dado que la instancia NAT va a realizar trabajo de enrutado de paquetes para otras instancias, si tiene activa esta comprobación no podrá enrutar el tráfico correctamente. Nuestra instancia NAT está lista para su uso:




Tablas de enrutado

Para nuestro entorno necesitaremos definir dos tablas de enrutado:
  • Main route table: O tabla de enrutado principal. Es la tabla de rutas por defecto que se genera cuando creamos nuestra VPC. Debemos definir esta tabla para que envie directamente por la interfaz el trafico local (10.0.0.0/16) y el resto de tráfico lo encamine hacia la instancia de NAT. Asociaremos esta tabla de enrutado a la subred de backend.
  • Custom route table: O tabla de enrutado personalizada. Será una nueva tabla de rutas que crearemos. Al igual que la anterior, el tráfico local se enviará directamente por la interfaz y el resto de tráfico se enviará al Internet Gateway que creamos al principio. Asociaremos esta tabla de enrutado a la subred de frontend.
Vemos el proceso de creación en la consola AWS. Iremos a servicios VPC --> Route Tables. Para nuestro ejemplo la tabla de rutas rtb-a8011eca es la principal asociada a la VPC 10.0.0.0/16. En la pestaña 'Routes' añadiremos la ruta por defecto (0.0.0.0/0) y como objetivo (Tarjet) seleccionaremos la instancia de NAT:


A continuación en la pestaña 'Associations' asociaremos la subred de backend (10.0.1.0/24) a la tabla de rutas principal:



Ahora añadiremos la tabla de enrutado personalizada pulsando el botón 'Create Route Table' y seleccionado nuestra VPC 10.0.0.0/16. Seleccionamos la nueva tabla de rutas y en la pestaña 'Routes' añadimos la ruta por defecto (0.0.0.0/16) hacia nuestro Internet Gateway creado en un apartado anterior:


De forma similar a lo realizado anteriormente, en la pestaña 'Associations' de la tabla de rutas asociaremos la subred de frontend (10.0.0.0/24):


Instancias de servicio

En este apartado voy a ser bastante mas escueto. Cread dos instancias t1.micro, usando como referencia los pasos seguidos para la instancia NAT. Una la llamaremos 'DB Server' y a la otra 'Web Server'. Como AMI recomiendo usar la estándar de Amazon para 64bits y como únicas recomendaciones afinad los security groups para permitir tráfico solo en los puertos y para las redes necesarias:

  • DB Server:

  • Web Server:


El servidor de base de datos, al estar en red de backend, no necesitará IP para comunicarse con Internet. Pero sí el servidor Web. Por lo que habrá que crear una EIP que asociar a la instancia 'Web Server'. Una vez concluido el proceso, deberemos tener tres instancias:



Para un testeo rápido que todo funciona:
  • Entrar en la instancia de NAT (debes adaptar el comando al uso de tu clave privada y EIP para la instancia de NAT): $ ssh -i TU_CLAVE_PRIVADA.pem ec2-user@TU_EIP
  • Actualizar paquetes (altamente recomendable por motivos de seguridad): $ sudo yum update;sudo yum upgrade
  • Desde la instancia de NAT acceder usando SSH a las instancias de base de datos y web. Para conocer las IP privadas de cada instancia usa la información que se muestra en la consola AWS. Actualizar los paquetes en cada instancia ($ sudo yum update;sudo yum upgrade) e instala MySQL y Apache respectivamente:
  • DB Server:
  • $ sudo yum install mysql-server
  • $ sudo chkconfig mysqld on
  • $ sudo service mysqld start

  • Web Server:
  • $ sudo yum install httpd
  • $ sudo chkconfig httpd on
  • $ sudo service httpd start

Si se ha configurado correctamente el entorno deberíamos poder ver la pagina web de ejemplo de nuestra instancia 'Web Server' desde cualquier navegador indicando su EIP asociada:


Lo dejaremos en este punto. En entregas posteriores aumentaremos la seguridad, incluiremos nuevos servicios y evolucionaremos nuestro entorno para hacer uso de algunas de las características mas interesantes y novedosas de AWS. 

Como podéis comprobar, definir y desplegar nuestra infraestructura de servicios en Amazon Web Services es fácil y rápido. Nos permite crear desde simples instancias virtuales para pocos servicios hasta complejas infraestructuras con alta disponibilidad, VPN y servicios de alta demanda con baja latencia a nivel global.