如何通过 AWS cloudformation 用户数据 bash 脚本在 cloud-init 阶段安装和启动服务?
How to install a service and lauch it during a cloud-init phase via AWS cloudformation user data bash script?
我需要在我的 EC2 实例上添加一个关闭挂钩来做一些资源清理工作。
此外,出于测试目的,我还可以手动启动和停止我的实例,我希望启动和关闭挂钩的触发方式与初始 bootstrap.
然后我决定通过 Cloudformation bash 脚本在 AWS EC2 Ubuntu 16.04 LTS 实例上安装脚本作为服务。
这是脚本的第一个原始版本:
UserData:
"Fn::Base64":
!Sub
- |
#!/usr/bin/env bash
BOOTSTRAP_SCRIPT_NAME=bootstrap
BOOTSTRAP_SCRIPT_PATH=/etc/init.d/${BOOTSTRAP_SCRIPT_NAME}
cat > /etc/init.d/boostrap <<EOF
### BEGIN INIT INFO
# Provides: ${BOOTSTRAP_SCRIPT_NAME}
# Required-Start: \$local_fs \$remote_fs \$network \$syslog \$named
# Required-Stop: \$local_fs \$remote_fs \$network \$syslog \$named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Bootstrap an instance
# Description: Bootstrap an instance
### END INIT INFO
function start() {
echo "STARTUP on $(date)"
}
function stop() {
echo "SHUTDOWN on $(date)"
}
case "$1" {
start)
start | tee -a /var/log/${BOOTSTRAP_SCRIPT_NAME}.log
;;
stop)
stop | tee -a /var/log/${BOOTSTRAP_SCRIPT_NAME}.log
;;
}
EOF
chmod +x ${BOOTSTRAP_SCRIPT_PATH}
update-rc.d -f ${BOOTSTRAP_SCRIPT_NAME} remove
update-rc.d ${BOOTSTRAP_SCRIPT_NAME} defaults
在这个版本中,bootstrap 脚本永远不会启动。
我很快明白 bootstrap 脚本是在 cloud-init 阶段安装的,顺便说一下,在 linux sysv init 阶段安装的,不会参与当前的 init 阶段.. .(如果这是错误的告诉我 ;-))
然后我决定手动启动它,例如 cloudformation bash 示例中的 apache2。我在脚本末尾添加了以下行。
${BOOTSTRAP_SCRIPT_PATH} start
我又测试了一遍,修复后在bootstrap.log文件中看到了"STARTUP on XXX"日志。
但是当我试图在控制台中停止实例时,bootstrap.log 文件中没有出现 "SHUTDOWN on XXX" 日志...
我登录实例并尝试手动 start/stop 脚本...所有启动和关闭日志都显示为 8-O。然后我假设由于 boostrap 脚本未被识别为初始化脚本,因此不会在实例停止或终止时调用停止回调...(如果这是错误的告诉我 ;-))
然后我从 AWS 控制台多次启动和停止实例,并且启动和关闭消息仍然出现在日志中。
这证实了我的假设。日志仅在第一个初始化和关闭周期期间丢失。
所以我做了一些奇怪和丑陋的事情......我用这个替换了最后一行开始命令:
reboot -n
该脚本现在可以按我的需要工作,但我认为应该有一种更简洁的方法来启用我的脚本,或者至少在 cloud-init 期间的关闭阶段启用我的脚本,而无需重新启动...
是否有人对此问题有最佳解决方案或更多详细信息?
PS :我尝试了 init u
和 telinit u
而不是重新启动但没有成功
原因似乎是bootstrap第一次没有作为服务启动。它是 运行 作为一个普通的脚本。尝试将以下行添加到您的用户数据中,而不是 ${BOOTSTRAP_SCRIPT_PATH} start
:
sudo service ${BOOTSTRAP_SCRIPT_NAME} start
我需要在我的 EC2 实例上添加一个关闭挂钩来做一些资源清理工作。
此外,出于测试目的,我还可以手动启动和停止我的实例,我希望启动和关闭挂钩的触发方式与初始 bootstrap.
然后我决定通过 Cloudformation bash 脚本在 AWS EC2 Ubuntu 16.04 LTS 实例上安装脚本作为服务。
这是脚本的第一个原始版本:
UserData:
"Fn::Base64":
!Sub
- |
#!/usr/bin/env bash
BOOTSTRAP_SCRIPT_NAME=bootstrap
BOOTSTRAP_SCRIPT_PATH=/etc/init.d/${BOOTSTRAP_SCRIPT_NAME}
cat > /etc/init.d/boostrap <<EOF
### BEGIN INIT INFO
# Provides: ${BOOTSTRAP_SCRIPT_NAME}
# Required-Start: \$local_fs \$remote_fs \$network \$syslog \$named
# Required-Stop: \$local_fs \$remote_fs \$network \$syslog \$named
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Bootstrap an instance
# Description: Bootstrap an instance
### END INIT INFO
function start() {
echo "STARTUP on $(date)"
}
function stop() {
echo "SHUTDOWN on $(date)"
}
case "$1" {
start)
start | tee -a /var/log/${BOOTSTRAP_SCRIPT_NAME}.log
;;
stop)
stop | tee -a /var/log/${BOOTSTRAP_SCRIPT_NAME}.log
;;
}
EOF
chmod +x ${BOOTSTRAP_SCRIPT_PATH}
update-rc.d -f ${BOOTSTRAP_SCRIPT_NAME} remove
update-rc.d ${BOOTSTRAP_SCRIPT_NAME} defaults
在这个版本中,bootstrap 脚本永远不会启动。
我很快明白 bootstrap 脚本是在 cloud-init 阶段安装的,顺便说一下,在 linux sysv init 阶段安装的,不会参与当前的 init 阶段.. .(如果这是错误的告诉我 ;-))
然后我决定手动启动它,例如 cloudformation bash 示例中的 apache2。我在脚本末尾添加了以下行。
${BOOTSTRAP_SCRIPT_PATH} start
我又测试了一遍,修复后在bootstrap.log文件中看到了"STARTUP on XXX"日志。 但是当我试图在控制台中停止实例时,bootstrap.log 文件中没有出现 "SHUTDOWN on XXX" 日志...
我登录实例并尝试手动 start/stop 脚本...所有启动和关闭日志都显示为 8-O。然后我假设由于 boostrap 脚本未被识别为初始化脚本,因此不会在实例停止或终止时调用停止回调...(如果这是错误的告诉我 ;-))
然后我从 AWS 控制台多次启动和停止实例,并且启动和关闭消息仍然出现在日志中。 这证实了我的假设。日志仅在第一个初始化和关闭周期期间丢失。
所以我做了一些奇怪和丑陋的事情......我用这个替换了最后一行开始命令:
reboot -n
该脚本现在可以按我的需要工作,但我认为应该有一种更简洁的方法来启用我的脚本,或者至少在 cloud-init 期间的关闭阶段启用我的脚本,而无需重新启动...
是否有人对此问题有最佳解决方案或更多详细信息?
PS :我尝试了 init u
和 telinit u
而不是重新启动但没有成功
原因似乎是bootstrap第一次没有作为服务启动。它是 运行 作为一个普通的脚本。尝试将以下行添加到您的用户数据中,而不是 ${BOOTSTRAP_SCRIPT_PATH} start
:
sudo service ${BOOTSTRAP_SCRIPT_NAME} start