Terraform 在导入当前状态后要求"ami"和"instance_type"



我有一个在 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和阿米.导入我的状态后,它存在于 terraform.tf 状态中。我需要手动传递此数据吗?有没有办法自动化这个过程?

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 永远无法检测到任何差异。

相关内容

  • 没有找到相关文章

最新更新