¿Cómo configuro cloud-init en AMI personalizadas en AWS? (CentOS)


Definir datos de usuario para instancias en AWS parece realmente útil para realizar todo tipo de acciones de tipo bootstrap. Desafortunadamente, tengo que usar una AMI CentOS personalizada que no se originó en una de las AMI proporcionadas por razones PCI, por lo que cloud-init no está ya instalado y configurado. Solo quiero que establezca un nombre de host y ejecute un pequeño script bash. ¿Cómo hago que funcione?

Author: whereswalden, 2014-05-01

3 answers

Cloud-init es una herramienta muy poderosa, pero muy indocumentada. Incluso una vez que está instalado, hay muchos módulos activos por defecto que sobrescriben cosas que puede que ya haya definido en su AMI. Aquí hay instrucciones para una configuración mínima desde cero:

Instrucciones

  1. Instale cloud-init desde un repositorio estándar. Si le preocupa PCI, probablemente no quiera usar los repositorios personalizados de AWS.

    # rpm -Uvh https://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
    # yum install cloud-init
    
  2. Editar /etc/cloud/cloud.cfg, un archivo yaml, para reflejar la configuración deseada. A continuación se muestra una configuración mínima con documentación para cada módulo.

    #If this is not explicitly false, cloud-init will change things so that root
    #login via ssh is disabled. If you don't want it to do anything, set it false.
    disable_root: false
    
    #Set this if you want cloud-init to manage hostname. The current
    #/etc/hosts file will be replaced with the one in /etc/cloud/templates.
    manage_etc_hosts: true
    
    #Since cloud-init runs at multiple stages of boot, this needs to be set so
    #it can log in all of them to /var/log/cloud-init.
    syslog_fix_perms: null
    
    #This is the bit that makes userdata work. You need this to have userdata
    #scripts be run by cloud-init.
    datasource_list: [Ec2]
    datasource:
      Ec2:
        metadata_urls: ['http://169.254.169.254']
    
    #modules that run early in boot
    cloud_init_modules:
     - bootcmd  #for running commands in pre-boot. Commands can be defined in cloud-config userdata.
     - set-hostname  #These 3 make hostname setting work
     - update-hostname
     - update-etc-hosts
    
    #modules that run after boot
    cloud_config_modules:
     - runcmd  #like bootcmd, but runs after boot. Use this instead of bootcmd unless you have a good reason for doing so.
    
    #modules that run at some point after config is finished
    cloud_final_modules:
     - scripts-per-once  #all of these run scripts at specific events. Like bootcmd, can be defined in cloud-config.
     - scripts-per-boot
     - scripts-per-instance
     - scripts-user
     - phone-home  #if defined, can make a post request to a specified url when done booting
     - final-message  #if defined, can write a specified message to the log
     - power-state-change  #can trigger stuff based on power state changes
    
    system_info:
      #works because amazon's linux AMI is based on CentOS
      distro: amazon
    
  3. Si hay un {[4] {} en[5]}, eliminarlo.

  4. Para aprovechar esta configuración, defina los siguientes datos de usuario para las instancias nuevas:

    #cloud-config
    hostname: myhostname
    fqdn: myhostname.mydomain.com
    runcmd:
     - echo "I did this thing post-boot"
     - echo "I did this too"
    

    También puede simplemente ejecutar un script bash reemplazando #cloud-config con #!/bin/bash y poniendo el script bash en el cuerpo, pero si lo hace, debe eliminar todos los módulos relacionados con el nombre de host de cloud_init_modules.


Notas adicionales

Tenga en cuenta que esta es una configuración mínima, y cloud-init es capaz de administrar usuarios, claves ssh, puntos de montaje, etc. Consulte las referencias a continuación para obtener más documentación sobre esas características específicas.

En general, parece que cloud-init hace cosas basadas en los módulos especificados. Algunos módulos, como "disable-ec2-metadata", hacen cosas simplemente al ser especificados. Otros, como "runcmd", solo hacen cosas si su los parámetros se especifican, ya sea en la nube.cfg, o en cloud-config userdata. La mayor parte de la documentación a continuación solo le dice qué parámetros son posibles para cada módulo, no cómo se llama el módulo, sino la nube predeterminada.cfg debe tener una lista completa de módulos para empezar. La mejor manera que he encontrado para desactivar un módulo es simplemente eliminarlo de la lista.

En algunos casos, "rhel" puede funcionar mejor para la etiqueta "distro" que "amazon". En realidad no me he dado cuenta cuando.


Referencias

 48
Author: whereswalden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-21 17:30:15

Ampliando la respuesta anterior para cualquiera que intente crear una AMI de CentOS que esté cloud-init habilitada (y capaz de ejecutar realmente sus scripts de CloudFormation), puede tener algún éxito haciendo lo siguiente:{[16]]}

  1. inicie una AMI de marketplace CentOS con actualizaciones: asegúrese de que cloud-init esté presente o sudo yum install -y cloud-init
  2. rm -rf /var/lib/cloud/data
  3. rm -rf /var/lib/cloud/instance
  4. rm -rf /var/lib/cloud/instances/*
  5. reemplace /etc/cloud/cloud.cfg con la configuración en la respuesta por encima, pero asegúrese de establecer distro: rhel
  6. Añadir los ayudantes de CloudFormation(http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-helper-scripts-reference.html)
  7. crear una imagen AMI a partir de esta instancia

Tenía un heck de un tiempo tratando de averiguar por qué mi UserData no estaba siendo invocado hasta que me di cuenta de que las imágenes en el mercado, naturalmente, solo ejecutar su UserData una vez por instancia Y, por supuesto, ya se habían ejecutado. Eliminar los indicadores que ya tenían ejecutado junto con el cambio de distro: rhel en el archivo cloud.cfg hizo el truco.

Para los curiosos, el valor distro: debe corresponder a uno de los scripts de python en /usr/lib/python2.6/site-packages/cloudinit/distros. Resulta que la AMI que lancé no tenía amazon.py, por lo que debe usar rhel para CentOS. Dependiendo de la AMI que inicie y la versión de cloud-init, YMMV.

 5
Author: bigfoot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-10 21:31:17

Aquí hay un breve tutorial sobre cómo ejecutar scripts durante el inicio usando cloud-init en AWS EC2 (CentOS).

Este tutorial explica:

  • cómo configurar el archivo de configuración /etc/cloud/cloud.cfg
  • cómo la ruta de la nube/var/lib/cloud/scripts parece que
  • los archivos de script bajo la ruta de la nube usando un ejemplo, y
  • cómo comprobar si los archivos de script se ejecutan durante el inicio de la instancia

Archivo de Configuración

El siguiente archivo de configuración está en AWS CentOS6. Para Amazon Linux, consulte aquí.

# cat /etc/cloud/cloud.cfg
manage_etc_hosts: localhost
user: root
disable_root: false
ssh_genkeytypes: [ rsa, dsa ]

cloud_init_modules:
 - resizefs
 - update_etc_hosts
 - ssh

cloud_final_modules:
 - scripts-per-once
 - scripts-per-boot
 - scripts-per-instance
 - scripts-user

Árbol de directorios

Esto es lo que la ruta de la nube /var/lib/cloud/scripts parece:

# cd /var/lib/cloud/scripts
# tree `pwd`
/var/lib/cloud/scripts
├── per-boot
│     └── per-boot.sh
├── per-instance
│     └── per-instance.sh
└── per-once
       └── per-once.sh

Contenido de los archivos de Script

Aquí están los contenidos de los archivos de script de ejemplo.
Los archivos deben estar bajo user root. Vea mi camino en creando el arranque script .

# cat /var/lib/cloud/scripts/per-boot/per-boot.sh
#!/bin/sh
echo per-boot: `date` >> /tmp/per-xxx.txt

# cat /var/lib/cloud/scripts/per-instance/per-instance.sh
#!/bin/sh
echo per-instance: `date` >> /tmp/per-xxx.txt

# cat /var/lib/cloud/scripts/per-once/per-once.sh   
#!/bin/sh
echo per-once: `date` >> /tmp/per-xxx.txt

Resultado de la Ejecución

En el caso de la puesta en marcha inicial

# cat /tmp/per-xxx.txt
per-once: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:30:16 JST 
per-instance: 1 January 3, 2013 Thursday 17:30:16 JST

En el caso de un reinicio

# cat /tmp/per-xxx.txt
per-once: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:30:16 JST 
per-instance: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:32:24 JST

En el caso de start from en el IAM

# cat /tmp/per-xxx.txt
per-once: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:30:16 JST 
per-instance: 1 January 3, 2013 Thursday 17:30:16 JST 
per-boot: 1 January 3, 2013 Thursday 17:32:24 JST 
per-boot: 1 January 3, 2013 Thursday 17:44:08 JST

Referencia
Se examinó el momento en el que se ejecuta el script en cloud-init (CentOS6) (traducido)

 4
Author: Chetabahana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-12 07:23:27