在我的Terraform AWS码头群模块中,我使用云init初始化EC2实例。然而,Terraform说,在云-init完成之前,资源已经准备好了。是否有一种方法可以让它等待云init完成,理想情况下不使用SSHing,或者检查端口是否使用null资源。
发布于 2020-05-31 15:34:03
您的template_cloudinit_config.和管理人员都使用工人他们也有ec2:CreateTags.
您可以使用像trajano/terraform-docker-swarm-aws/cloudinit-complete这样的EC2资源标记来指示cloudinit已经完成。
您可以将最后一部分添加到每个部分,以调用一个标记脚本:
部分{ filename = "tag_complete.sh“内容= local.tag_complete_script content_type =”text/x“}
并声明tag_complete_script如下:
locals {
tag_complete_script = <<-EOF
#!/bin/bash
instance_id="${TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/instance-id}"
aws ec2 create-tags --resources "$instance_id" --tags 'Key=trajano/terraform-docker-swarm-aws/cloudinit-complete,Value=true'
EOF
}然后使用null_resource,等待标记出现(在我的手机上写了这个,所以使用它作为一个总体想法,但我不希望它在没有测试和编辑的情况下工作):
resource "null_resource" "wait_for_cloudinit" {
provisioner "local-exec" {
command = <<-EOF
#!/bin/bash
poll_tags="aws ec2 describe-tags --filters 'Name=resource-id,Values=${join(",", aws_instance.managers[*].id)}' 'Name=key,Values=trajano/terraform-docker-swarm-aws/cloudinit-complete' --output text --query 'Tags[*].Value'"
expected='${join(",", formatlist("true", aws_instance.managers[*].id))}'
$tags="$($poll_tags)"
while [[ "$tags" != "$expected" ]] ; do
$tags="$($poll_tags)"
done
EOF
}
}这样,您就可以在cloudinit完成后运行的任何资源上对null_resource.wait_for_cloudinit具有依赖关系。
发布于 2021-08-19 14:40:59
另一种可能的方法是使用AWS系统管理器运行命令,如果您的AMI可用的话。
使用Terraform创建一个使用cloud-init status --wait命令的SSM文档,然后从本地提供程序触发命令,并等待它完成。以这种方式,你不需要玩标签,你是100%确定云-init已经完成。
这是您可以用Terraform创建的文档的一个示例:
resource "aws_ssm_document" "cloud_init_wait" {
name = "cloud-init-wait"
document_type = "Command"
document_format = "YAML"
content = <<-DOC
schemaVersion: '2.2'
description: Wait for cloud init to finish
mainSteps:
- action: aws:runShellScript
name: StopOnLinux
precondition:
StringEquals:
- platformType
- Linux
inputs:
runCommand:
- cloud-init status --wait
DOC
}然后,您可以在EC2实例块中或在空资源中使用本地提供程序,直到您需要使用它。
供给者或多或少会是这样的:
provisioner "local-exec" {
interpreter = ["/bin/bash", "-c"]
command = <<-EOF
set -Ee -o pipefail
export AWS_DEFAULT_REGION=${data.aws_region.current.name}
command_id=$(aws ssm send-command --document-name ${aws_ssm_document.cloud_init_wait.arn} --instance-ids ${self.id} --output text --query "Command.CommandId")
if ! aws ssm wait command-executed --command-id $command_id --instance-id ${self.id}; then
echo "Failed to start services on instance ${self.id}!";
echo "stdout:";
aws ssm get-command-invocation --command-id $command_id --instance-id ${self.id} --query StandardOutputContent;
echo "stderr:";
aws ssm get-command-invocation --command-id $command_id --instance-id ${self.id} --query StandardErrorContent;
exit 1;
fi;
echo "Services started successfully on the new instance with id ${self.id}!"
EOF
}https://stackoverflow.com/questions/62116684
复制相似问题