aws_instance - 更改卷大小

ha9*_*3ar 10 amazon-ec2 amazon-web-services terraform

我正在尝试增加我的 ami 的根卷的大小ami-0d013c5896434b38a- 我正在使用 Terraform 来配置它。

只是为了澄清 - 我只有一个例子。我想确保如果我需要增加磁盘空间,我不必先破坏机器。弹性(EC2)是我相信它可行的理由。

有谁知道这是否可行?是的,我可以简单地进行terraform plan一次预演,但只需仔细检查即可。

Lar*_*ars 23

I'm running Terraform 1.0.1 and would like to change my volume_size from 20gb to 30gb.

After run terraform apply

[...]
# aws_instance.typo3_staging_1 will be updated in-place
~ resource "aws_instance" "staging_1" {
    id                          = "i-0eb2f8af6c8ac4125"
    tags                        = {
    "Name" = "Staging 1"
    "Team" = "DevOps"
  }
  # (28 unchanged attributes hidden)

  ~ root_block_device {
      tags                  = {}
    ~ volume_size           = 20 -> 30
    # (8 unchanged attributes hidden)
  }
  # (4 unchanged blocks hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
[...]
Run Code Online (Sandbox Code Playgroud)

我发现 terraform 不会破坏系统。现在,一个简单的“是”就可以改变音量。约 33 秒后 root_block_device 已更改。

登录 ec2 显示没有任何更改。df显示旧的 20GB 根分区大小。但是简单的sudo reboot增加了10GB的磁盘空间,并且没有破坏当前的系统。该实例上的所有 docker 容器都按预期运行。完美的。

我的 Terraform 资源配置是aws_instance

resource "aws_instance" "staging_1" {

  instance_type = "t3.medium"
  ebs_optimized = true

  ami                    = "ami-001183208be54f75c"
  key_name               = aws_key_pair.master_key.key_name
  subnet_id              = aws_subnet.web_development_private_a.id
  vpc_security_group_ids = [aws_security_group.ec2_staging.id]

  root_block_device {
    volume_size = 30 # in GB <<----- I increased this!
    volume_type = "gp3"
    encrypted   = true
    kms_key_id  = data.aws_kms_key.customer_master_key.arn
  }

  # This is for T3 only (doesn't apply to M5/R5/...)
  # standard: Baseline of 20% or 30% CPU. Short bursts of 100% CPU are possible, but under a budget. Throttled, if budget is 0.
  # unlimited: Always 100% CPU possible, but costs are higher, if over burst budget.
  credit_specification {
    cpu_credits = "unlimited"
  }

  metadata_options {
    http_endpoint = "enabled"
    http_tokens   = "required"
  }

  lifecycle {
    prevent_destroy = true
  }

  tags = {
    Name = "Staging 1"
    Team = "DevOps"
  }
  volume_tags = {
    Name = "Staging 1"
    Team = "DevOps"
  }
}

Run Code Online (Sandbox Code Playgroud)


Raf*_*faP 5

根据快速测试,可以通过AWS 控制台或 AWS CLI实现,但不能通过 Terraform 实现。

volume_size在如下定义中将参数从 10更改为 20aws_instance会导致实例的销毁/重新创建。使用 Terraform 0.15.0。

如果您需要继续使用 Terraform 管理实例,请考虑以下选项:(1) 在 Terraform 外部(aws 控制台或 CLI)执行修改,以及 (2) 将修改后的资源导入回 Terraform。

aws_instance在答案的第二部分中,我描述了一个通过控制台将修改后的状态重新导入 Terraform 的简单示例。

免责声明:执行此操作需要您自担风险,并在非生产环境中进行适当的测试。仔细阅读terraform import命令文档中的警告

测试在 Terraform 中完成的 EBS 修改 - 需要替换实例

resource "aws_instance" "testebs" {
  availability_zone           = local.aznames[0]
  ami                         = data.aws_ami.ubuntu.id
  instance_type               = "t2.micro"
  associate_public_ip_address = true
  key_name                    = "zzzzzzzz"
  ebs_block_device {
    device_name = "/dev/sda1"
    volume_size = 20
  }
}
Run Code Online (Sandbox Code Playgroud)

我将完整的配置和输出粘贴到下面terraform plan。这ami是最新的 Ubuntu 20.04 eu-west-1,而不是最初问题中的版本。

文件ebstest.tf

terraform {
  required_version = "~> 0.15.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.0"
    }
  }
}

provider "aws" {
  region  = "eu-west-1"
  profile = "xxxxxxx"
}

data "aws_ami" "ubuntu" {
  most_recent = true
  filter {
    name = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }
  owners = ["099720109477"] # Canonical
}

data "aws_availability_zones" "available" {
  state = "available"
}
locals {
  aznames = data.aws_availability_zones.available.names
}

resource "aws_instance" "testebs" {
  availability_zone           = local.aznames[0]
  ami                         = data.aws_ami.ubuntu.id
  instance_type               = "t2.micro"
  associate_public_ip_address = true
  key_name                    = "zzzzzzzz"
  ebs_block_device {
    device_name = "/dev/sda1"
    volume_size = 20
  }
  tags = {
    Name = "testebs-${local.aznames[0]}"
  }
}
Run Code Online (Sandbox Code Playgroud)

输出terraform plan

$ terraform plan
aws_instance.testebs: Refreshing state... [id=i-0e1fededb2e432a98]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # aws_instance.testebs must be replaced
-/+ resource "aws_instance" "testebs" {
      ~ arn                          = "arn:aws:ec2:eu-west-1:xxxxxxxxxxxxx:instance/i-0e1fededb2e432a98" -> (known after apply)
      ~ cpu_core_count               = 1 -> (known after apply)
      ~ cpu_threads_per_core         = 1 -> (known after apply)
      - disable_api_termination      = false -> null
      - ebs_optimized                = false -> null
      - hibernation                  = false -> null
      + host_id                      = (known after apply)
      ~ id                           = "i-0e1fededb2e432a98" -> (known after apply)
      ~ instance_state               = "running" -> (known after apply)
      ~ ipv6_address_count           = 0 -> (known after apply)
      ~ ipv6_addresses               = [] -> (known after apply)
      - monitoring                   = false -> null
      + outpost_arn                  = (known after apply)
      + password_data                = (known after apply)
      + placement_group              = (known after apply)
      ~ primary_network_interface_id = "eni-0a923724fec1e76ce" -> (known after apply)
      ~ private_dns                  = "ip-172-31-13-57.eu-west-1.compute.internal" -> (known after apply)
      ~ private_ip                   = "172.31.13.57" -> (known after apply)
      ~ public_dns                   = "ec2-3-250-102-86.eu-west-1.compute.amazonaws.com" -> (known after apply)
      ~ public_ip                    = "3.250.102.86" -> (known after apply)
      ~ secondary_private_ips        = [] -> (known after apply)
      ~ security_groups              = [
          - "default",
        ] -> (known after apply)
      ~ subnet_id                    = "subnet-192e767f" -> (known after apply)
        tags                         = {
            "Name" = "testebs-eu-west-1a"
        }
      ~ tenancy                      = "default" -> (known after apply)
      ~ vpc_security_group_ids       = [
          - "sg-d7dc5a9a",
        ] -> (known after apply)
        # (7 unchanged attributes hidden)

      - credit_specification {
          - cpu_credits = "standard" -> null
        }

      + ebs_block_device { # forces replacement
          + delete_on_termination = true
          + device_name           = "/dev/sda1"
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = 20
          + volume_type           = (known after apply)
        }
      - ebs_block_device { # forces replacement
          - delete_on_termination = true -> null
          - device_name           = "/dev/sda1" -> null
          - encrypted             = false -> null
          - iops                  = 100 -> null
          - snapshot_id           = "snap-0f4b18aebb4264157" -> null
          - tags                  = {} -> null
          - throughput            = 0 -> null
          - volume_id             = "vol-01eade74ebeba666f" -> null
          - volume_size           = 10 -> null
          - volume_type           = "gp2" -> null
        }

      ~ enclave_options {
          ~ enabled = false -> (known after apply)
        }

      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)
        }

      ~ metadata_options {
          ~ http_endpoint               = "enabled" -> (known after apply)
          ~ http_put_response_hop_limit = 1 -> (known after apply)
          ~ http_tokens                 = "optional" -> (known after apply)
        }

      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_interface_id  = (known after apply)
        }

      ~ root_block_device {
          ~ delete_on_termination = true -> (known after apply)
          ~ device_name           = "/dev/sda1" -> (known after apply)
          ~ encrypted             = false -> (known after apply)
          ~ iops                  = 100 -> (known after apply)
          + kms_key_id            = (known after apply)
          ~ tags                  = {} -> (known after apply)
          ~ throughput            = 0 -> (known after apply)
          ~ volume_id             = "vol-01eade74ebeba666f" -> (known after apply)
          ~ volume_size           = 10 -> (known after apply)
          ~ volume_type           = "gp2" -> (known after apply)
        }
    }

Plan: 1 to add, 0 to change, 1 to destroy.
Run Code Online (Sandbox Code Playgroud)

通过 AWS 控制台测试修改并从 terraform 导入资源(请参阅上面的免责声明/警告)。

  1. 按照答案的前一部分创建具有 10G 卷的实例。
  2. 在AWS控制台中将EBS卷大小修改为20G。(没有在操作系统级别扩展音量——供读者练习:D)
  3. 列出状态文件中的 Terraform 项目并选择要删除aws_instance状态的资源
$ terraform state list
data.aws_ami.ubuntu
data.aws_availability_zones.available
aws_instance.testebs
Run Code Online (Sandbox Code Playgroud)
  1. 删除资源terraform state rm的状态 ( ) aws_instance
$ terraform state rm aws_instance.testebs
Removed aws_instance.testebs
Successfully removed 1 resource instance(s).
Run Code Online (Sandbox Code Playgroud)
  1. 使用terraform import,导入修改后的 EC2 实例的aws_resource使用信息。instance-id
$ terraform import aws_instance.testebs  i-xxxxxxxxxxxxxxxx
aws_instance.testebs: Importing from ID "i-xxxxxxxxxxxxxxxx"...
aws_instance.testebs: Import prepared!
  Prepared aws_instance for import
aws_instance.testebs: Refreshing state... [id=i-xxxxxxxxxxxxxxxx]

Import successful!

The resources that were imported are shown above. These resources are now in your Terraform state and will henceforth be managed by Terraform.
Run Code Online (Sandbox Code Playgroud)
  1. 验证 terraform 是否可以正确管理导入的实例(通过 terraform 修改实例并验证行为)


mar*_*ber 0

ebs_block_device - (可选)一个或多个配置块,以及附加到实例的附加 EBS 块设备。块设备配置仅适用于资源创建。

因此,根据文档,ebs_block_device只能在创建资源期间应用。在您的情况下,它是一个需要重新创建的 EC2 实例。

  • OP实际上是在询问root_block_device,而不是ebs_block_device。使用最新的 terraform 版本,您可以调整根的大小而不破坏任何东西。 (3认同)