AWS: пример CloudFormation EC2 UserData – установка пакета, добавление задачи в cron и обновление UserData

By | 03/06/2018
 

Задача: добавить в CloudFormation шаблон установку git и cron-задачу.

Быстрый пример работы с UserData в CloudFormation шаблоне.

Ресурс AWS::EC2::Instance сейчас выглядит так:

 

    ...
    "EC2Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Properties" : {
        "Tags" : [
          {"Key" : "Name", "Value" : { "Fn::Join" : [ "-", [ {"Ref" : "AWS::StackName"}, "ec2"] ] } },
          {"Key" : "Env", "Value" : {"Ref" : "AWS::StackName"} },
          {"Key" : "Client", "Value" : {"Ref" : "ClientTag"} }
        ],
        "InstanceType" : { "Ref" : "EC2InstanceType" },
        "SecurityGroupIds" : [
          {
            "Ref": "EC2SecurityGroup"
          }
        ],
        "KeyName" : { "Ref" : "EC2KeyName" },
        "ImageId" : { "Ref" : "EC2AMIID"  },
        "AvailabilityZone" : { "Fn::FindInMap" : [ "SubnetsAZs", "public-subnets", "EC2PublicSubnet1a" ] },
        "SubnetId": { "Ref" : "EC2PublicSubnet" },
      }
    },
    ...

Установка git

Добавляем параметр UserData и установку git:

...
        "SubnetId": { "Ref" : "EC2PublicSubnet" },
        "UserData"       : { "Fn::Base64" : { "Fn::Join" : ["\n", [
          "#!/bin/bash -v",
          "apt-get update",
          "apt-get -y install git"
        ]]}}
      }
    },
...

Запускаем, проверяем:

ssh -i ads-ec2.pem ubuntu@54.***.***.91 'git --version'
git version 2.7.4

Добавление cron-задачи

Аналогично – добавим crontask.

cron задач будет несколько, поэтому добавим их из файла.

Проверяем на рабочей машине:

cd /tmp/
echo "* * * * * echo test" >> crontests.txt
crontab crontests.txt
crontab -l
* * * * * echo test

Добавляем её в CloudFormation шаблон:

...
        "UserData"       : { "Fn::Base64" : { "Fn::Join" : ["\n", [
          "#!/bin/bash -v",
          "apt-get update",
          "apt-get -y install git",
          "echo \"* * * * * /bin/echo testcrontask1\" >> /root/crontasks",
          "/usr/bin/crontab /root/crontasks"
        ]]}}
...

Пересоздаём стек, проверяем на интансе:

ssh -i ../../../credentials/aws/ads-ec2.pem ubuntu@184.***.***.64 sudo crontab -l
* * * * * /bin/echo testcrontask1

Повторный запуск UserData

Помните, что UserData выполняется только при создании интанса.

О том, что скрипт был выполнен – CloudInit заносит запись в каталог sem (от semaphore):

root@ip-10-0-2-8:~# cat /var/lib/cloud/instances/i-0fe563bba7c0b2426/sem/config_scripts_user
1360: 1520316115.5601585

Описание всех каталогов есть тут>>>.

Если интанс просто остановить, и изменить UserData, например через AWS Console – то изменения не будут применены.

Проверяем:

Запускаем, и:

root@ip-10-0-2-8:~# crontab -l
* * * * * /bin/echo testcrontask1

Задача не изменилась, семафор – тоже:

root@ip-10-0-2-8:~# cat /var/lib/cloud/instances/i-0fe563bba7c0b2426/sem/config_scripts_user
1360: 1520316115.5601585

Хотя задача для CloudInit обновилась:

root@ip-10-0-2-8:~# grep -r test /var/lib/cloud/
/var/lib/cloud/instances/i-0fe563bba7c0b2426/scripts/part-001:echo "* * * * * /bin/echo testcrontask2" >> /root/crontasks
/var/lib/cloud/instances/i-0fe563bba7c0b2426/user-data.txt:echo "* * * * * /bin/echo testcrontask2" >> /root/crontasks
/var/lib/cloud/instances/i-0fe563bba7c0b2426/user-data.txt.i:echo "* * * * * /bin/echo testcrontask2" >> /root/crontasks

ОК – удаляем файл /var/lib/cloud/instances/i-0fe563bba7c0b2426/sem/config_scripts_user, и перезапускаем инстанс:

root@ip-10-0-2-8:~# rm /var/lib/cloud/instances/i-0fe563bba7c0b2426/sem/config_scripts_user
root@ip-10-0-2-8:~# reboot
Connection to 184.***.***.64 closed by remote host.
Connection to 184.***.***.64 closed.

После перезапуска – проверяем:

...
Last login: Tue Mar  6 06:32:40 2018 from 188.***.***.114
ubuntu@ip-10-0-2-8:~$ sudo -s
root@ip-10-0-2-8:~# crontab -l
* * * * * /bin/echo testcrontask2

Готово.