【问题标题】:Use of S3 in Terraform aws_instance.connection.private_key and aws_key_pair.public_key在 Terraform aws_instance.connection.private_key 和 aws_key_pair.public_key 中使用 S3
【发布时间】:2020-08-20 19:13:31
【问题描述】:

我正在尝试使用 terraform cloud 并且不想在存储库中提交 SSH 密钥。我当前的配置如下所示:


resource "aws_key_pair" "project" {
  key_name   = "project"
  public_key = file(".ssh/id_rsa.pub")
}

resource "aws_instance" "example" {
  ami           = "ami-08ee2516c7709ea48"
  instance_type = "t2.micro"
  security_groups = [
    aws_security_group.ssh_allow.name,
    aws_security_group.http_allow.name
  ]
  key_name = aws_key_pair.project.key_name

  connection {
    type        = "ssh"
    user        = "centos"
    private_key = file(".ssh/id_rsa")
    host        = self.public_ip
  }

  provisioner "remote-exec" {
    inline = [
      "sudo yum -y install nginx",
      "sudo systemctl start nginx"
    ]
  }

  lifecycle {
    create_before_destroy = true
  }

是否可以从远程存储中引用文件,例如 S3?

类似这样的:

resource "aws_key_pair" "project" {
  key_name   = "project"
  public_key = s3_file("bucket/ssh/id_rsa.pub")
}

有可能吗?

我尝试使用数据提供者

data "aws_s3_bucket_object" "public_key" {
  bucket = "com.project.infrastructure"
  key    = ".ssh/project.pub"
}

data "aws_s3_bucket_object" "private_key" {
  bucket = "com.project.infrastructure"
  key    = ".ssh/project"
}

resource "aws_key_pair" "project" {
  key_name   = "project"
  public_key = data.aws_s3_bucket_object.public_key.body
}

但收到此错误:

Error: "public_key": required field is not set

  on example.tf line 28, in resource "aws_key_pair" "project":
  28: resource "aws_key_pair" "project" {


AWS 安全凭证是正确的,我可以从存储桶下载文件

aws s3api get-object --bucket com.project.infrastructure --key .ssh/project private_key

null_resource 的实验也失败了

resource "null_resource" "download_key" {
  provisioner "local-exec" {
    when    = create
    command = "aws s3api get-object --bucket com.project.infrastructure --key .ssh/project.pub project.pub"
  }
  provisioner "local-exec" {
    when    = create
    command = "aws s3api get-object --bucket com.project.infrastructure --key .ssh/project project"
  }
}

resource "aws_key_pair" "project" {
  key_name   = "project"
  depends_on = [null_resource.download_key]
  public_key = file("project.pub")
}

resource "aws_instance" "example" {
  ami           = "ami-08ee2516c7709ea48"
  instance_type = "t2.micro"
  security_groups = [
    aws_security_group.ssh_allow.name,
    aws_security_group.http_allow.name
  ]
  key_name = aws_key_pair.project.key_name

  connection {
    type        = "ssh"
    user        = "centos"
    private_key = file("project")
    host        = self.public_ip
  }


  provisioner "local-exec" {
    command = "echo ${aws_instance.example.public_ip} > ip_address.txt"
  }

  provisioner "remote-exec" {
    inline = [
      "sudo yum -y install nginx",
      "sudo systemctl start nginx"
    ]
  }

  depends_on = [aws_s3_bucket.saritasa_bucket, aws_key_pair.project]

  lifecycle {
    create_before_destroy = true
  }

  tags = module.project_config.tags

}

然后我收到以下错误

➜ terraform plan    

Error: Error in function call

  on example.tf line 42, in resource "aws_key_pair" "project":
  42:   public_key = file("proect.pub")

Call to function "file" failed: no file exists at project.pub.

【问题讨论】:

    标签: terraform terraform-provider-aws terraform0.12+


    【解决方案1】:

    一种选择是从空资源调用您的aws s3api get-object
    然后在你的 aws_key_pair 资源上使用depends_on

    类似这样的:

    provider "aws" {
      region = "us-east-1"
    }
    
    resource "random_string" "key" {
      length  = 8
      special = false
    }
    
    resource "null_resource" "download_key" {
      triggers = {
        build_number = timestamp()
      }
    
      provisioner "local-exec" {
        when    = create
        command = "aws s3api get-object --bucket bucket123456123654 --key dir/data ${path.module}/${random_string.key.result}"
      }
    }
    
    resource "aws_key_pair" "project" {
      depends_on = [null_resource.download_key]
      key_name   = "project"
      public_key = file("${path.module}/${random_string.key.result}")
    }
    
    

    【讨论】:

    • 这不起作用。我已经用修改过的 terraform 代码和我得到的错误更新了我的原始问题。简而言之,我收到错误Call to function "file" failed: no file exists at project.pub.。因此,文件存在的验证似乎发生在计划步骤,因此这里没有调用空资源。
    • ...作为记录,将您的 PUBLIC 密钥添加到您的存储库没有任何问题...您不应该添加的是您的私有密钥
    • 我更新了我的答案以包括相对路径也使用random_string 作为文件名......但我觉得这是一个黑客,你应该将你的公钥添加到回购中
    猜你喜欢
    • 2020-03-23
    • 1970-01-01
    • 2021-05-28
    • 2022-11-03
    • 2021-03-09
    • 2017-12-02
    • 2020-08-15
    • 2020-10-28
    • 2018-06-06
    相关资源
    最近更新 更多