Debugando mensajes de error en terraform con CloudTrail

Hoy me he encontrado con un mensaje de error al aplicar terraform para crear un ASG y su Launch Template en AWS que no me ha parecido intuitivo.

Error: Error creating AutoScaling Group: 
AccessDenied: You are not authorized to use launch template: name-of-the-template
	status code: 403, request id: 12425678-7890-4567-1234-14ef2ea89123

Bueno, en realidad era un «Access Denied». ¿Fácil, no? Pues no, o por lo menos no para mí. El usuario que aplicaba terraform ya tenía los permisos que a priori parecía que necesitaba para poder crear ese recurso y sus asociados.

Entonces… ¿cómo saber de qué permisos se me está quejando? Aquí es donde entra CloudTrail. Lo que he hecho es básicamente buscar los eventos para el usuario con el que estaba ejecutando el comando, pues no he encontrado la forma de usar la request-id que nos devuelve el error. Recuerda que pueden tardar varios minutos hasta que aparezcan los eventos en CloudTrail, así que paciencia.

Continuar leyendo «Debugando mensajes de error en terraform con CloudTrail»

introducción a JQ con ejemplos

Hoy rescato un borrador que ha estado desde siempre en el blog. Básicamente quería empezar un post de introducción a jq que tuviera ejemplos prácticos, pues todo lo que he visto por ahí no me ha parecido muy práctico si estás empezando.

Lo primero, decir que jq pone a nuestra disposición una herramienta online para trastear con jq en jqplay.org, que nos puede venir bien.

Empezamos con el siguiente ejemplo:

❯ cat /tmp/jq-example
[
    {
        "nombre": "A",
        "reglas": [
            {
                "regla": "1",
                "posicion": "1"
            },
            {
                "regla": "2",
                "posicion": "2"
            }
        ]
    },
    {
        "nombre": "B",
        "reglas": [
            {
                "regla": "1",
                "posicion": "1"
            },
            {
                "regla": "3",
                "posicion": "3"
            }
        ]
    }
]
Continuar leyendo «introducción a JQ con ejemplos»

Kubernetes – Apuntes del CKA

Bueno, aquí dejo algunos apuntes (ojo, ésto no es una guía ni una biblia; son sólo eso, apuntes) tras repasarme los cursos «Kubernetes Quick Start» y «Cloud Native Certified Kubernetes Administrator (CKA)» de LinuxAcademy.com

Cómo instalar Docker + Kubernetes from scratch en CentOS

Usando Flannel para la gestión de la red.

Dejo un copy&paste de las instrucciones originales de LinuxAcademy.

    #The first thing that we are going to do is use SSH to log in to all machines. Once we have logged in, we need to elevate privileges using sudo.
     sudo su  

    #Disable SELinux.
     setenforce 0
     sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux

    #Enable the br_netfilter module for cluster communication.
     modprobe br_netfilter
     echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables

    #Disable swap to prevent memory allocation issues.
     swapoff -a
     vim /etc/fstab.orig  ->  Comment out the swap line

    #Install the Docker prerequisites.
     yum install -y yum-utils device-mapper-persistent-data lvm2

    #Add the Docker repo and install Docker.
     yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
     yum install -y docker-ce

    #Configure the Docker Cgroup Driver to systemd, enable and start Docker
     sed -i '/^ExecStart/ s/$/ --exec-opt native.cgroupdriver=systemd/' /usr/lib/systemd/system/docker.service 
     systemctl daemon-reload
     systemctl enable docker --now

    #Add the Kubernetes repo.
     cat < /etc/yum.repos.d/kubernetes.repo
     [kubernetes]
     name=Kubernetes
     baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
     enabled=1
     gpgcheck=0
     repo_gpgcheck=0
     gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
             https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
     EOF

    #Install Kubernetes.
     yum install -y kubelet kubeadm kubectl

    #Enable Kubernetes. The kubelet service will not start until you run kubeadm init.
     systemctl enable kubelet

*Note: Complete the following section on the MASTER ONLY!

    #Initialize the cluster using the IP range for Flannel
     kubeadm init --pod-network-cidr=10.244.0.0/16

    #Copy the kubeadmin join command. Exit sudo and run the following:
     mkdir -p $HOME/.kube
     sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
     sudo chown $(id -u):$(id -g) $HOME/.kube/config

    #Deploy Flannel.
     kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

    #Check the cluster state.
     kubectl get pods --all-namespaces

*Note: Complete the following steps on the NODES ONLY!

    #Run the join command that you copied earlier (this command needs to be run as sudo), then check your nodes from the master.
     kubectl get nodes

Nota:
Al final k8s es una capa encima de docker que usa la API de docker para manipularlo. Puedes correr un docker ps en las instancias para ver exactamente qué está pasando por debajo de k8s (en docker)

Continuar leyendo «Kubernetes – Apuntes del CKA»

Yaml essentials

YAML

Inicialmente llamado «Yet Another Markup Language» (YAML), que sin embargo no es un Markup Language, si no que ha acabado siendo un lenguage de serialización de datos fácilmente legible por humanos, razón por la que cambió su nombre a «YAML Ain’t Markup Language».

Pensado para ser fácilmente legible por humanos, por lo que sus casos de uso son:
– Ficheros de configuración
– Almacenage de datos

Sintáxis
– Usa (2) espacios para indentar (nunca tabs!)
– La indentación agrupa cosas que van juntas
– Guiones para listas
– Dos puntos para key: values (atención al espacio tras los dos puntos)
– Usa comentarios con # seguido de un espacio en blanco (o tab)

Estilos:
– Block: el habitual
– Flow: es una extensión de JSON

Tipos
– Mappings: key:values
– Secuencias: array o lista de items, uno por línea precedido de un guión
– Escalares: strings, números o booleanos

Podemos partir un string en múltiples líneas (preservando el salto de línea) mediante «|» o sin preservarlo (pese a tener salto de línea dentro del yaml para facilitar la lectura) con «>»

schedule: |
  2018-10-01 - Whatever here
  2018-10-02 - And here
done_by: >
  A large sentence that
  has been broken into pieces
  but will be presented together.

Estructuras:
– Opcionalmente, un yaml file puede empezar con tres guiones. Ésto es obligatorio cuando usas herramientas como «Ansible».
– Los tres guiones también se pueden usar para separar diferentes documentos dentro de un mismo fichero.

Los anchors sirven para reutilizar datos dentro del fichero yaml. Seteamos la línea o el bloque con &anchorname y hacemos referencia a él con *anchorname.

 
locations:
  &EUlocations
  - Spain
  - Portugal
  - Italy
samelocations:
  *EUlocations

Más info
https://yaml.org/start.html
Linux Academy: Yaml essentials

Site Reliability Engineering (SRE): principios

He querido resumir en un post, los principios que se explican en el libro «Site Reliability Engineer» de Google (gratis y online).

CAPITULO 1 & 2 – INTRO

Además de programar, a un SRE se le pide conocimientos avanzados de cómo funciona el sistema UNIX a nivel interno, y de networking (capas de la 1 a la 3)

La clave está en dedicar al menos un 50% del tiempo en automatizar las tareas de operaciones o a hacer tareas de ingeniería (mejorar la fiabilidad, el performance, etc.). De esta manera, evitas tener un equipo que crezca a la vez que crece la infraestructura (y por tanto, las tareas de operaciones si no estuvieran automatizadas).

También es clave dedicarle tiempo a los postmortem para aquellos incidentes relevantes. En caso contrario, no se estará aprovechando la oportunidad de mejorar nuestros sistemas.

El concepto de «error budget» es (1 – disponibilidad_acordada). Si se establece 99.99% de disponibilidad acordada, el error budget será de 0.01%. Este error budget se podrá usar para lo que se quiera, pero típicamente se usará para tomar riesgos deployando nuevas funcionalidades lo antes posible.

Aprox un 70% de las caídas son debidas a cambios en producción. Los SREs deben aplicar best practices para automatizar completamente los cambios (progresivos) en producción así como el rollback.

Las alertas del sistema de monitorización deberían interpretarse y solucionarse de forma automática, y a partir de ahí, únicamente deberían notificar a un humano cuando éstos necesiten tomar parte.

Continuar leyendo «Site Reliability Engineering (SRE): principios»

Cómo lidiar con unassigned shards en Elasticsearch


Lo primero es lo primero, saber qué significa el estado del cluster de elasticsearch:

  • Green: Cluster 100% operacional con todos los shards, tanto primarios como réplicas asignados.
  • Yellow: Todos los shards primarios asignados, pero al menos hay problemas con una réplica. El funcionamiento de las búsquedas no se ve afectado, pero la alta disponibilidad del cluster podría estar comprometida.
  • Red: Al menos un shard primario tiene problemas. Tus búsquedas devolverán resultados incompletos y el indexado podría devolver alguna excepción.

Fuentes: [elastic.co] [chrissimpson.co.uk]

Red cluster. ¿Y ahora qué?

En el siguiente ejemplo, vemos un cluster en estado RED, con 2 shards no asignados.

[ec2-user@myfakeserver ~]$ curl http://elasticsearch.myfakecluster.com:9200/_cluster/health?pretty
{
  "cluster_name" : "myfakecluster",
  "status" : "red",
  "timed_out" : false,
  "number_of_nodes" : 6,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 44,
  "active_shards" : 88,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 2,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 97.77777777777777
}

Muchas de las ocasiones en los que me he encontrado con un cluster con unassigned shards ha sido por falta de espacio en disco, ya sea porque el cluster en sí se estaba quedando sin espacio, o porque había caído alguno de los data nodes. Así pues, tras verificar que no haya problemas de espacio, seguramente deberíamos revisar que el cluster tenga el número y tipo de nodos esperados.

[ec2-user@myfakeserver ~]$ curl -s http://elasticsearch.myfakecluster.com:9200/_cat/nodes?v
ip            heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
10.10.13.74            62          69   1    0.01    0.01     0.00 m         *      i-00e943d383ac0e36a
10.10.12.224           10          74   0    0.00    0.00     0.00 di        -      i-0fb30da02fa44654f
10.10.14.191           17          68   1    0.30    0.16     0.05 m         -      i-0c3f5e9ffe51580de
10.10.13.26            10          75   0    0.00    0.00     0.00 di        -      i-088d4398987bbcbe4
10.10.14.79            21          71   0    0.00    0.00     0.00 di        -      i-0d02b207abeb67c6b
10.10.12.4             34          68   1    0.04    0.03     0.00 m         -      i-087e0c009c10493d6

Continuar leyendo «Cómo lidiar con unassigned shards en Elasticsearch»

EBS/RDS Snapshots

¿Cómo funcionan los EBS snapshots?

Los snapshots de EBS son incrementales (excepto el primero que hagas sobre un volumen EBS); únicamente incluyen los bloques modificados desde el último snapshot. Cada snapshot contiene la información necesaria para hacer un restore completo de tus datos hasta el momento de hacer el snapshot, es decir, contiene referencias a los snapshot anteriores, lo que permite realizar un full restore (hasta el momento de hacer el snapshot) a partir de ese determinado snapshot.

[Fuente]

¿Se puede eliminar un snapshot EBS de forma segura?

Cuando eliminas un snapshot, solamente se eliminan los datos únicos de ese snapshot. Es importante recalcar que aunque el snapshot se elimine, los datos referenciados por otros snapshots se mantendrán. A la práctica ésto significa que si no necesitas poder hacer restores desde las fechas/horas específicas en las que se realizaron los diferentes snapshots, puedes eliminarlos todos excepto el último, que aun así podrás realizar un restore completo.

[Fuente]

Continuar leyendo «EBS/RDS Snapshots»

Un primer vistazo a Puppet


Bueno, hoy traigo un popurrí de conceptos sobre Puppet que espero sirvan para tener una primera idea de algunas de sus características y opciones. Si eres un master of puppets, éste no es tu post.

Puppet es una de las herramientas de gestión centralizada de servidores (y workstations) más conocidas. En su página web, ofrecen varios videos gratuitos que explican con más detalle qué es y cómo funciona.

Bolt y Puppet Tasks

Bolt: standalone, opensource agentless task runner para ejecutar ad-hoc imperative tasks en entornos pequeños.

$gem install bolt

Puppet tasks: para resolver tareas que no encajan bien en el modelo tradicional puppet. Las Puppet Tasks son una forma simple y rápida de actualizar paquetes al instante, reiniciar servicios o ejecutar cualquier otro tipo de acción similar en tus nodos.

# Ejecuto un comando en dos nodos (boron2 y boron5)
$bolt command run "netstat -an | grep 'tcp.*LISTEN'" -n boron2,boron5

# Pongo mis comandos en un script en cualquier lenguaje que entiendan mis nodos. 
# Este script se copiará a los nodos, en un dir temp, lo ejecutará, devolverá 
# el output y después lo eliminará
$bolt script run myscript.sh -n boron-2,boron-5

Continuar leyendo «Un primer vistazo a Puppet»

Reemplazar un data nodo de Elasticsearch de forma segura

Es probable que en alguna ocasión necesitemos reemplazar uno de nuestros nodos de datos del cluster de Elasticsearch. Una opción (a lo loco, y nada recomendable) sería directamente eliminar el nodo, y añadir uno nuevo, el cual, en algún momento se sincronizará con el cluster. Obviamente lo malo de esta opción, es que el cluster quedará en status yellow o red mientras no termine la sincronización.

Una buena opción (probado en un ES 5.6.3) para hacer de este proceso, un proceso seguro y controlado, es como primer paso, quitar el nodo del cluster, esperar a que los shards (primarios y réplicas) se re-asignen, y una vez tengamos el nodo desacoplado del cluster, reemplazarlo. La idea es continuar con el cluster en «green» durante todo el proceso.

A continuación los pasos.

Continuar leyendo «Reemplazar un data nodo de Elasticsearch de forma segura»

Usa diferentes versiones de terraform con tfenv

Cuando trabajas en grandes entornos gestionados con terraform, es muy probable que tengas que trabajar a su vez con diferentes versiones de terraform, según requieran cada unos de los proyectos.

En lugar de descargar las diferentes versiones que necesitemos, renombrando los ejecutables, moviéndolos a algún directorio dentro del PATH y jugando con enlaces simbólicos, podemos símplemente usar el maravilloso tfenv.

Descarga e instalación

Para empezar a usar tfenv, lo único que necesitaremos será clonar el repositorio (por ejemplo en nuestra home) y crear un enlace simbólico para que tfenv esté disponible en el PATH.

[adri@adri ~]$ git clone https://github.com/kamatama41/tfenv.git ~/.tfenv
Cloning into '/home/adri/.tfenv'...
remote: Counting objects: 716, done.
remote: Total 716 (delta 0), reused 0 (delta 0), pack-reused 716
Receiving objects: 100% (716/716), 102.65 KiB | 0 bytes/s, done.
Resolving deltas: 100% (449/449), done.
Checking connectivity... done.

[adri@adri ~]$ sudo ln -s ~/.tfenv/bin/* /usr/local/bin

Continuar leyendo «Usa diferentes versiones de terraform con tfenv»