Hola , mi nombre es Vanessa López y éste es mi primer post en Azurebrains, como administradora cloud, me gustaría escribir sobre una de las buenas prácticas (si no es una de las mas importantes) como es la seguridad a la hora de desplegar nuestras infraestructuras en la nube, ya que, si queremos aumentar la seguridad y el control sobre nuestros “secretos”, una buena forma de hacerlo es utilizando el servicio de Azure Key Vault.
Basándonos en el modelo “Zero Trust«, he elegido diferentes soluciones gestionadas que nos permiten la interacción entre los diferentes servicios de una forma segura, a la vez que permite aumentar la trazabilidad de las acciones (quién, cómo y cuándo). Estas soluciones serían Bitbucket, Terraform Cloud y Azure Key Vault, que nos permiten el versionado de nuestro código, que sea reproducible, que sea automatizable y a la vez que colaborativo.
Azure Key Vault
El servicio de Azure Key Vault, nos permite almacenar de forma segura en la nube secretos, certificados o claves criptográficas, controlando así qué usuarios y/o aplicaciones tienen acceso a éstos.
Para este proyecto, crearé un almacén de claves y en él dos secretos, los cuales serán utilizados por la instancia que desplegaremos, a éstos secretos además, solo podrá acceder una entidad (SPN) que crearemos para este propósito.
El almacén, se creara en un grupo y región distinto de donde se desplegara la maquina virtual, manteniendo así mayor seguridad y disponibilidad.
Terraform Cloud
Terraform Cloud es un servicio gestionado, que nos permite la ejecución de nuestro código remotamente, almacenar en un espacio de trabajo (workspace) la configuración, el estado y variables, para posteriormente realizar el despliegue en el contexto de este workspace, pudiendo ademas auditarlo para saber quién y cuándo lo realizó.
Estas auditorias, podemos gestionarlas de forma mas exhaustiva con la herramienta Terraform Sentinel, creando políticas basadas en nuestras necesidades.
Utilizaremos Terraform Cloud para crear dos workspaces distintos donde ejecutar el código de los diferentes despliegues en cada uno de ellos, uno que contendrá el despliegue del Key Vault y otro para el despliegue de la instancia que será ejecutado automaticamente después de desplegar el Key Vault.
Bitbucket
Una buena práctica es contar con un repositorio donde cada miembro del equipo pueda trabajar independientemente del resto, permitiendo así, la colaboración entre diferentes miembros del equipo para aportar nuevas funcionalidades a los despliegues. Aquí es donde entra Git, permitiendo versionar el código y crear “ramas“ independientes donde trabajar para luego finalmente, unificarlas a una sola rama y ponerla en producción.
Bitbucket utiliza Git, nos permite gestionar dicho código, revisando y aprobando los cambios que realicemos en éste para posteriormente, como será en nuestro caso, ejecutar la planificación y despliegue de la infraestructura.
Solución
En el siguiente diagrama de arquitectura, se muestra las soluciones propuestas y la integración entre ellas:
Prerequisitos
Para la ejecución de este proyecto, los siguientes prerequisitos serán necesarios:
- Un equipo con Git instalado para la copia local de nuestro repositorio.
- Bitbucket, donde tendremos alojado el código Git para la revisión y aprobación final del mismo.
- Terraform Cloud, conectado a Bitbucket mediante “Token”.
- Una suscripción de Azure.
- Un Service Principal Name (SPN) con el rol de “Contributor“ para permitir a Terraform Cloud el despliegue de nuestra infraestructura en dicha suscripción.
Configuración de Bitbucket
Instalaremos Git en nuestro ordenador, una vez hecho, lo primero que tenemos que hacer es crear un espacio de trabajo remoto, y posteriormente un repositorio dentro del mismo.
Ahora clonaremos dicho repositorio en donde hayamos instalado Git.
Configuración de Terraform Cloud
Aquí crearemos una organización, la conectaremos con el sistema de control de versiones Bitbucket y le indicaremos el proyecto donde queremos trabajar, agregaremos también dos workspaces donde se ejecutará el código correspondiente para los distintos despliegues.
Creación de la Organización
Crearemos una organización sobre la que trabajaremos indicándole un nombre único, así como una dirección de correo.
Conexión con Bitbucket
Ahora creamos el workspace y lo conectaremos al proveedor de versiones, en nuestro caso utilizaremos Bitbucket.
Cuando seleccionamos el proveedor, nos mostrará los datos que necesitaremos introducir en Bitbucket para realizar la conexión entre ambas plataformas.
Creación del consumidor en Bitbucket
Con estos datos, desde Bitbucket crearemos un consumidor OAuth para permitir la conexión con Terraform Cloud.
Le indicaremos un nombre y la organización, así como la URL de callback, marcaremos además que es un consumidor privado y los permisos correspondientes.
Nota: Hay que prestar atención a los permisos habilitados.
Una vez guardada la configuración, aparecerá ya creado el consumidor con la clave y el secreto que añadiremos a la configuración del proveedor en Terraform Cloud.
Con estos datos, desde Terraform Cloud le indicaremos un nombre, dicha clave y secreto y conectaremos finalmente ambas plataformas.
Selección del repositorio en Bitbucket
Elegiremos el repositorio donde esta hospedado nuestro código Terraform.
Creación de los Workspaces
Indicaremos un nombre a nuestro workspace, seguiremos el mismo procedimiento para crear los dos workspaces, en nuestro caso, se llamarán east-us2 y west-us2.
Una vez creados, accederemos a la configuración de éstos y le indicaremos el directorio de trabajo para Terraform de cada uno de ellos:
Le indicaremos también a ambos que sólo se ejecute el despliegue cuando haya cambios en el código de su propio directorio de trabajo.
Nota: La rama del VCS por defecto es “master”.
Conexión con Azure
Ahora, conectaremos Azure con Terraform Cloud creando un Service Principal Name (SPN).
Primero iniciaremos sesión en Azure mediante la CLI:
az login
Para crear la entidad de servicio con los permisos correspondientes para administrar recursos en la suscripción utilizaremos el siguiente comando:
az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/SUBSCRIPTION_ID"
Desde el portal de Azure podemos comprobar como se ha creado:
Este comando nos devolverá los siguientes valores:
{
"appId": "00000000-0000-0000-0000-000000000000",
"displayName": "azure-cli-2017-06-05-10-41-15",
"name": "http://azure-cli-2017-06-05-10-41-15",
"password": "0000-0000-0000-0000-000000000000",
"tenant": "00000000-0000-0000-0000-000000000000"
}
Estos valores, los añadiremos como variables en Terraform Cloud:
- appId es el client_id en Terraform.
- password es el client_secret en Terraform.
- tenant es el tenant_id en Terraform.
Configuración de las variables
Con estos valores, pasamos a configurarlos como variables de entorno en cada uno de los workspaces.
Es importante destacar, que dichas variables tiene que ser llamadas tal cual aparecen en la imagen para que el “provider” de Azure las pueda interpretar.
Código y despliegue
Una vez establecidas las conexiones entre las diferentes plataformas, solo nos queda que preparar el código.
Os dejo el enlace con el repositorio donde podréis obtener el código utilizado para el despliegue de este proyecto:
https://bitbucket.org/proyecto-key-vault/deployment/src/master/
Cuando empezamos con el despliegue del código es importante situarse en el directorio raíz donde están ubicados los proyectos, añadiremos todo el proyecto con git add .
tras esto procedemos a hacer commit -m ”Mensaje de commit”
y finalmente lo subimos al origen (Bitbucket) con push
.
Veremos ahora que en Terraform Cloud, nos aparece el plan, tras confirmar, comenzará la creación de los recursos del primer workspace (west-us2):
Tras este, y automáticamente, comienza el despliegue del siguiente wirkspace (east-us2):
Resultado Final
Una vez finalizado el despliegue, desde el portal podemos observar como se han creado los distintos recursos.
Grupo de recursos para el Key Vault.
Secretos.
Grupo de recursos para la maquina virtual.
Ahora probamos a conectarnos a la máquina por SSH con los secretos de usuario y contraseña que acabamos de crear:
Verifico si el servicio de Nginx esta corriendo:
Ademas de comprobar su funcionamiento vía web:
Espero que este post os haya gustado y os sea útil para futuras implementaciones. ¡Hasta la próxima!