Las copias de seguridad son un elemento importante dentro de las técnicas de seguridad pasiva que nos permiten, ante un incidente de seguridad, recuperarnos de él minimizando el riesgo de pérdida de información. Básicamente consisten en decidir de qué queremos guardar una copia y cada cuánto tiempo (y por cuánto tiempo la mantendremos). Las repuestas a estas preguntas dependen de la importancia de los datos, de la frecuencia de cambio y de los recursos que tengamos para almacenar las copias. Una vez tomadas estas decisiones, deberemos ejecutar el plan de copias, con la herramienta elegida (en nuestro caso, Bacula) en todos y cada uno de los equipos (servidores o no) afectados por el plan.
Bacula es una herramienta de copias de seguridad compuesta por diversos elementos que deben configurarse y, en concreto, Bacula-file debe instalarse en todos los nodos en los que se quiera realizar copias. En otra entrada posterior (la que hace referencia el playbook common) se explicará cómo se realiza dicha instalación. Para minimizar las tareas de administración y gestión del sistema de copias de seguridad, en la infraestructura IT de la EPS hemos desarrollado el playbook de Ansible baculaAdmon (baculaAdmon.yml) de la infraestructura de ejemplo descrita aquí y aquí. Este playbook permite realizar la configuración del servicio Bacula de manera centralizada para todos los elementos que intervienen en el servicio, además de poder:
- realizar los cambios una sola vez (en lugar de realizarlo para cada servidor) y
- comprobar la sintaxis antes de ejecutarlo en cada servidor y en caso de error, deshacer los cambios y continuar ejecutando la configuración anterior.
El código del playbook baculaAdmon.yml es:
# Bacula Servers Group - hosts: baculaAdmon* remote_user: ansible become: yes become_user: root become_method: sudo tasks: - include: group_by.yml - include: pathFacts.yml - hosts: baculaAdmon* gather_facts: False remote_user: ansible become: yes become_user: root become_method: sudo roles: - baculaAdmon
En la infraestructura de ejemplo, el servidor de Bacula se llama baculaAdmon1 (abarcado por el patrón utilizado baculaAdmon*)
Se dispone de un rol con dos tareas y un template. Los cambios se realizan en el template que no es más que el fichero de configuración del Bacula Director para todos los servidores. Los trabajos se generan todos de manera automática a partir de una serie de variables declaradas en group_vars/all/baculaAdmon:
- baculaAdmonFilesets -> Configuración de los Fileset en el fichero bacula-dir.conf (fichero de configuración del director Bacula) para todos los servidores. Esta variable es una lista con los siguientes atributos:
- compression -> Cadena de texto con la compresión a utilizar en el Fileset. Este atributo es opcional, si no se incluye la compresión por defecto será GZIP
- signature -> Cadena de texto con la firma a utilizar en el Fileset. Este atributo es opcional, si no se incluye la firma por defecto será MD5
- name -> Se trata de una cadena de texto con el nombre del Fileset que posteriormente serán llamados desde otra variables para realizar los trabajos de backup
- includes -> Lista con los directorios a incluir en el Fileset
- excludes -> Lista con los directorios a excluir del Fileset (por lógica deberían ser subconjuntos de los componentes de la lista ‘includes‘. Este atributo es opcional, por defecto no se excluye nada.
Un ejemplo de declaración de esta variable es:
baculaAdmonFilesets: - name: "etc" includes: [ "/etc" ]
- baculaAdmonGlobal -> Configuración de los clientes y sus trabajos en el fichero bacula-dir.conf para todos los servidores. Esta variable es una lista con los siguientes atributos.
- label -> Este atributo tiene la función de clave del item. Esto quiere decir que si más adelante queremos hacer referencia a una entrada (para eliminarla o sobreescribirla) lo haremos por este atributo.
- fileset -> Se trata de una cadena de texto con el nombre del Fileset a utilizar para realizar los trabajos de backup.
Ambos atributos label y fileset son obligatorios y deben declararse. En caso de que alguno no exista, la entrada de ese cliente con ese fileset no será tenida en cuenta en el fichero de configuración.
Ejemplo:
baculaAdmonGlobal: - label: "etc" fileset: "etc"
- baculaAdmonGroup -> Configuración de los clientes y sus trabajos para un grupo específico
Se trata de una lista de variables, cada una de ellas con dos atributos. El atributo llamado group con el nombre del grupo al que se le aplicarán las declaraciones, y el atributo que incluye las entradas a aplicar (este atributo es en realidad una lista). Esta lista de entradas incluye para cada item dos atributos idénticos a los que hemos visto para la variable baculaAdmonGlobal (label y fileset) y con la misma finalidad.
Podemos ‘sobreescribir’ o ‘eliminar’ las entradas globales desde esta variable (en esta lista de entradas por grupo). Para:
Sobreescribir entradas globales -> Declaramos el atributo label con el mismo texto que el atributo global, y definimos el resto de atributos con los valores que queramos en este caso concreto.
Eliminar entradas globales -> Declaramos el atributo label con el mismo texto que el atributo global, y no declaramos el resto de atributos (no se declaran con valor nulo, sino que en la entrada sólo existirá el atributo ‘label’).
El resto de entradas que se escriban (y no coincida el label con ninguna ‘global’) se añadirán en el fichero a las globales.
Por ejemplo:
baculaAdmonGroup: - group: mysql backup: - label: "root.scripts" fileset: "root.scripts"
- baculaAdmonHost -> Configuración de los clientes y sus trabajos para un servidor específico. Se trata de una lista de variables, cada una de ellas con dos atributos: host que indicará el nombre del servidor al que se le aplicarán las declaraciones; y el segundo atributo, cuya finalidad es idéntica a la del segundo atributo de las variables baculaAdmonGlobal y baculaAdmonGroup. También podemos ‘sobreescribir’ o ‘eliminar’ igual que hemos visto para la anterior variable.
- Un ejemplo de declaración de esta variable:
-
baculaAdmonHost: - host: version backup: - label: "svn" fileset: "svn"
-
Las variables de los templates (roles/baculaAdmon/templates/etc/bacula/bacula-dir.conf.j2 y roles/baculaAdmon/templates/etc/bacula/bacula-sd.conf.j2) lo que hacen es modificar el fichero para que se ajuste a todos y cada uno de los servidores. Es posible sobreescribir los valores de estas variables en los ficheros por grupo o por host pero no es recomendable: es mejor práctica utilizar las variables del fichero para grupos y servidores específicos. Además, en estos templates también se configuran, al principio de los ficheros, las conexiones entre el bacula-director y el resto de componentes de Bacula.
Como todos los playbooks, para su ejecución disponemos de una orden (ansible-playbook baculaAdmon.yml) y la opción correspondiente del menú, b, logrando con ambas actualizar todos los servidores del grupo baculaAdmon.
Una característica muy buena de todos estos playbooks es que, junto con la ejecución diaria en background, cada vez que se añade un nuevo servidor al inventario, aunque no ejecutemos ningún playbook “a mano”, al disponer de la ejecución en background, éste será añadido y configurado, en el caso que nos ocupa, para realizarle copias de seguridad. Es decir, no volverá a ocurrir lo de…”¡¡¡se me olvidó darlo de alta en el Bacula!!!”.
¡Esperamos que os sea útil!
One Reply to “Playbook de Ansible para configurar copias de seguridad con Bacula”