【问题标题】:Terraform asking for "ami" and "instance_type" after importing current stateTerraform 在导入当前状态后询问“ami”和“instance_type”
【发布时间】:2020-04-20 22:31:01
【问题描述】:

我有一个在 aws 上手动创建的 EC2 实例。我需要使用 terraform 在我的实例中运行 bash 脚本,而无需重新创建 EC2 实例。这是我的 tf 文件。

instance.tf

resource "aws_key_pair" "mykey" {
  key_name   = "mykey"
  public_key = file(var.PUBLIC_KEY)
}
resource "aws_instance" "example" {

key_name      = aws_key_pair.mykey.key_name
 provisioner "file" {
   source="script.sh"
   destination="/tmp/script.sh"
}
 connection {
    type ="ssh"
    user ="ubuntu"
    private_key=file(var.PRIVATE_KEY)
    host        = coalesce(self.public_ip, self.private_ip)
 }
}

vars.tf

   variable "INSTANCE_USERNAME" {
      default = "ubuntu"
    }
    variable "PUBLIC_KEY" {
      default = "mykey.pub"
    }
    variable "PRIVATE_KEY" {
      default ="mykey"
    }
    variable "AMIS" {}
    variable "INSTANCE_TYPE" {}

provider.tf

provider  "aws"  {
   access_key = "sd**********"
   secret_key = "kubsd**********"
   region = "us-east-2"
}

我已经使用

导入了我的当前状态
terraform import aws_instance.example instance-id

这是我的状态文件

{
  "version": 4,
  "terraform_version": "0.12.17",
  "serial": 1,
  "lineage": "54385313-09b6-bc71-7c9c-a3d82d1f7d2f",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "aws_instance",
      "name": "example",
      "provider": "provider.aws",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "ami": "ami-0d5d9d301c853a04a",
            "arn": "arn:aws:ec2:us-east-2:148602461879:instance/i-054caec795bbbdf2d",
            "associate_public_ip_address": true,
            "availability_zone": "us-east-2c",
            "cpu_core_count": 1,
            "cpu_threads_per_core": 1,
            "credit_specification": [
              {
                "cpu_credits": "standard"
              }
            ],
continues...

但是当我运行 terraform plan 时,它会显示类似

的错误
Error: Missing required argument

  on instance.tf line 5, in resource "aws_instance" "example":
   5: resource "aws_instance" "example" {

The argument "ami" is required, but no definition was found.


Error: Missing required argument

  on instance.tf line 5, in resource "aws_instance" "example":
   5: resource "aws_instance" "example" {

The argument "instance_type" is required, but no definition was found.

我不明白为什么它要求 instance_type 和 ami 。导入我的状态后,它存在于 terraform.tf 状态中。我需要手动传递这些数据吗?有没有办法自动化这个过程?

【问题讨论】:

  • 导入只是将东西添加到状态中。您仍然需要定义资源以匹配它,以便 Terraform 可以进行差异检查以查看资源是否需要修改以匹配 Terraform 代码。这要求您至少设置资源的所有必需字段,amiinstance_typeaws_instance 资源的 2 个必需参数。
  • @ydaetskcoR ,所以我需要找到我的 ami 和 instance_type 并在我的资源中手动指定它吗??
  • 您可以设置任何虚拟值,然后查看差异显示的内容。或者您可以查看已导入的状态,然后对其进行设置,然后查看差异应该为空。
  • 您好@ydaetskcoR 我尝试 grep ami 和 instance_type 并将值导出为 TF_VAR_AMIS 和 TF_VAR_INSTANCE 并将这些值传递给 resource 。但是如果我删除 terraform.tfstate 然后再次尝试导入状态,它将显示缺少参数错误。有没有其他方法可以从 tfstates 调用值并传递给资源?

标签: terraform terraform-provider-aws


【解决方案1】:

terraform import 命令的存在允许您绕过通常的要求,即 Terraform 必须是创建代表配置中每个资源的远程对象的一个​​。您应该仅将其视为告诉 Terraform 您的 resource "aws_instance" "example" 块已连接到远程对象 instance-id 的一种方式(使用您在示例中显示的占位符)。您仍然需要告诉 Terraform 该对象的所需配置,因为 Terraform 的部分职责是在您的配置与远程对象(通过状态)不一致时注意到并制定计划进行更正。

你的情况是一个很好的例子,说明为什么 Terraform 不只是在terraform import 中自动为你写出配置:你似乎想从输入变量中设置这些参数,但 Terraform 无法知道这一点,除非你在配置中写出来:

resource "aws_instance" "example" {
  # I'm not sure how you wanted to map the list of images to one
  # here, so I'm just using the first element for example.
  ami           = var.AMIS[0] 
  instance_type = var.INSTANCE_TYPE
  key_name      = aws_key_pair.mykey.key_name
}

通过明确地写出来,Terraform 可以看到这些参数的值应该来自哪里。 (请注意,惯用的 Terraform 样式是让变量具有小写名称,如 instance_type,而不是大写名称,如 INSTANCE_TYPE。)

无法使用状态中的现有值来填充配置,因为这是 Terraform 流程的相反方向:创建 Terraform 计划会将配置与状态进行比较,并检测配置何时不同,然后生成操作这将使远程对象与配置匹配。使用状态中的值来填充配置会使对象失效,因为 Terraform 永远无法检测到任何差异。

【讨论】:

  • 嗨@Martin Atkins,我们可以使用 terraform 在不使用 terraform 创建的远程基础设施上执行脚本或命令吗?
猜你喜欢
  • 2019-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-14
  • 1970-01-01
  • 2021-07-02
  • 2021-05-25
  • 2021-09-25
相关资源
最近更新 更多