【问题标题】:Terraform AWS: Unable to copy file into EC2Terraform AWS:无法将文件复制到 EC2
【发布时间】:2021-05-15 02:56:05
【问题描述】:

我是 terraform 的新手。我有一个 Dockerized 应用程序,可以使用 docker-compose 文件进行部署。

我编写了一个 terraform 脚本,它创建了一个安全组、一台 EC2 机器,并运行了一个下载 docker 和 docker-compose 的脚本,我正在尝试将此 docker-compose 文件从本地机器上传到远程机器。每当 terraform 到达这一步时,都会产生以下错误:

aws_instance.docker_swarm: Provisioning with 'file'... 
Error: host for provisioner cannot be empty

下面是 terraform 模板:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 2.70"
    }
  }
}

provider "aws" {
  profile = var.profile
  region  = var.region
}

resource "aws_security_group" "allow_ssh_http" {
  name        = "allow_ssh_http"
  description = "Allow SSH and HTTP access to ports 22 and 1337"

  ingress {
    description = "SSH from everywhere"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "Access Port 1337 from Everywhere"
    from_port   = 1337
    to_port     = 1337
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "allow_ssh_http"
  }
}

resource "aws_instance" "docker_swarm" {
  ami           = var.amis[var.region]
  instance_type = var.instance_type
  key_name = var.key_name
  vpc_security_group_ids = [aws_security_group.allow_ssh_http.id]

    user_data = "${file("deployServices.sh")}"

  provisioner "file" {
    source      = "./docker-compose.yml"
    destination = "/home/ubuntu/docker-compose.yml"
  }
    tags = {
        Name = "NK Microservices Stack" 
    }
}

output "ec2_id" {
  value = aws_instance.docker_swarm.id
}

output "ec2_ip" {
  value = aws_instance.docker_swarm.public_ip
}

【问题讨论】:

    标签: amazon-web-services docker terraform infrastructure-as-code


    【解决方案1】:

    我认为您需要向provisioner 提供connection 的详细信息。例如:

    resource "aws_instance" "docker_swarm" {
      ami           = var.amis[var.region]
      instance_type = var.instance_type
      key_name = var.key_name
      vpc_security_group_ids = [aws_security_group.allow_ssh_http.id]
    
      user_data = "${file("deployServices.sh")}"
    
      provisioner "file" {
    
        source      = "./docker-compose.yml"
        destination = "/home/ubuntu/docker-compose.yml"
    
        connection {   
          host        = self.public_ip
          user        = "ubuntu"
          private_key = file("<path-to-private-ssh-key>")
        }   
    
      }
    
      tags = {
         Name = "NK Microservices Stack" 
      }
    }
    

    其中&lt;path-to-private-ssh-key&gt; 是与您的var.key_name 关联的ssh 密钥。

    【讨论】:

    • 在运行用户数据之前,我需要将文件放在机器上。我怎样才能做到这一点?
    • @NicolasElKhoury 您可以在用户数据脚本中添加一些等待循环,以检查文件是否存在。如果文件不存在,等待循环会休眠几秒钟,然后重试,直到找到文件。
    • @NicolasElKhoury 怎么样?
    【解决方案2】:

    Terraform 文档指出,您应该只将配置器用作最后的手段。

    除了启动脚本之外,用户数据还可以包含files。在尝试使用配置器之前,我肯定会推荐这种方法。或者您甚至可以将文件作为heredoc 包含在用户数据脚本中。

    或者,您可以在运行 Terraform 之前将文件复制到 S3,甚至使用 Terraform 到 upload the file to S3,然后简单地让 EC2 实例下载文件作为用户数据脚本的一部分。

    【讨论】:

      猜你喜欢
      • 2020-09-17
      • 2021-03-23
      • 1970-01-01
      • 2018-06-26
      • 2019-09-16
      • 1970-01-01
      • 2019-04-01
      • 2020-12-13
      • 1970-01-01
      相关资源
      最近更新 更多