Terraform公式教程即时播放

①安装指令

我能够用homebrew进行安装。

brew tap hashicorp/tap
brew install hashicorp/tap/terraform

设置命令行配置

在教程中,我们会设置路径并进行命令补全。但是我个人使用zsh,并通过历史记录来显示预测候选项,所以这里是路径。

用Terraform在Docker上运行

在这里开始以实际的方式,用Terraform实际运行Docker进行试验。首先创建一个目录。

open -a Docker
mkdir learn-terraform-docker-container
cd learn-terraform-docker-container

然后,创建一个名为 main.tf 的文件。这将成为 Terraform 的主要配置文件。

terraform {
  required_providers {
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 2.13.0"
    }
  }
}

provider "docker" {}

resource "docker_image" "nginx" {
  name         = "nginx:latest"
  keep_locally = false
}

resource "docker_container" "nginx" {
  image = docker_image.nginx.latest
  name  = "tutorial"
  ports {
    internal = 80
    external = 8000
  }
}

然后,在写了这个的状态下,运行下面的指令,项目就会启动起来(在这种状态下,资源还没有运行)。

terraform init

所以,当执行↓时,实际上会启动资源。

terraform apply

本次情况下进行了如下配置,启动了一个具有nginx镜像的Docker容器。同时将端口设置为80:8000,因此可以通过localhost:8000连接到nginx服务器。

要停止启动的资源,请执行以下步骤↓

terraform destroy

使用Terraform在AWS上创建资源。

使用Terraform启动AWS资源并查看。

与Docker时一样,在main.tf文件中编写配置。

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

  required_version = ">= 1.2.0"
}

provider "aws" {
  region  = "us-west-2"
}

resource "aws_instance" "app_server" {
  ami           = "ami-830c94e3"
  instance_type = "t2.micro"

  tags = {
    Name = "ExampleAppServerInstance"
  }
}

大概来说,从教程文件来看,每个设置项目的意图如下所示。

required_providers…Terraformを使う上で必須となるprovider。sourceでproviderの存在する場所、versionで利用するpvoviderのバージョンを指定している

provider…Terraformでリソースを管理するプラットフォーム的な何か。Docker、AWS、GCPみたいな粒度の値が入る。

resources…provider上で実際に立ち上げるリソース。これはシンプルだね

当您编写完设定文件后,可以像先前一样通过↓来启动。

terraform init
terraform apply

顺便提一下,在配置文件中可以进行格式和描述错误的检查,可以在CI等方面使用。

terraform fmt
terraform validate

遇到错误,所以记下来了。

terraform apply

执行。。。会出现以下错误。

aws_instance.app_server: Creating...
╷
│ Error: creating EC2 Instance: InvalidAMIID.NotFound: The image id '[ami-830c94e3]' does not exist
│ 	status code: 400, request id: 24596a32-6f55-49d6-b205-94a0bf5078f1
│ 
│   with aws_instance.app_server,
│   on main.tf line 16, in resource "aws_instance" "app_server":
│   16: resource "aws_instance" "app_server" {
│ 
╵

听起来好像找不到AMI!我看到这个消息之后开始做了一些调查,发现AMl的ID会因为不同的地区而不同。
在教程的 main.tf 文件中使用了 us-west-2 这个地区,但是我当然不想花钱,所以改成了 ap-northeast-1。然而,我没有改变AMI的ID,所以出现了错误。

aws ec2 describe-images --owners self amazon --region ap-northeast-1

当使用AWS CLI执行类似的命令时,可以在东京区域获取到由awsm官方所拥有的AMI。我认为如此,但由于获取结果不直观,所以我将在控制台上查看它。

当您启动EC2实例时,将会显示如下屏幕,您可以在这里选择适用于免费使用配额的映像。

Cursor_と_インスタンスを起動___EC2_Management_Console.png

由于有AMI ID,将其复制到 main.tf 文件中进行查看。

好的。terrafrom apply成功了,太棒了。

Cursor_と_インスタンス___EC2_Management_Console.png

当我真正查看控制台时,它已经启动了。真厉害。

顺便说一句,要查看已启动资源的详细信息,请执行以下操作↓。

terraform show

如果显示出类似的结果,那就可以了。

resource "aws_instance" "app_server" {
    ami                                  = "ami-078296f82eb463377"
    arn                                  = "..."
    associate_public_ip_address          = true
    availability_zone                    = "ap-northeast-1c"
    cpu_core_count                       = 1
    cpu_threads_per_core                 = 1
    disable_api_stop                     = false
    disable_api_termination              = false
    ebs_optimized                        = false
    get_password_data                    = false
    hibernation                          = false
    id                                   = "i-0413a991b88bc950e"
    instance_initiated_shutdown_behavior = "stop"
    instance_state                       = "running"
    instance_type                        = "t2.micro"
    ipv6_address_count                   = 0
    ipv6_addresses                       = []
    monitoring                           = false
    primary_network_interface_id         = "eni-04ae1cf226d4d833d"
    private_dns                          = "ip-172-31-3-118.ap-northeast-1.compute.internal"
    private_ip                           = "172.31.3.118"
    public_dns                           = "ec2-43-206-106-51.ap-northeast-1.compute.amazonaws.com"
    public_ip                            = "43.206.106.51"
    secondary_private_ips                = []
    security_groups                      = [
        "default",
    ]
    source_dest_check                    = true
    subnet_id                            = "subnet-0a658c50"
    tags                                 = {
        "Name" = "ExampleAppServerInstance"
    }
    tags_all                             = {
        "Name" = "ExampleAppServerInstance"
    }
    tenancy                              = "default"
    user_data_replace_on_change          = false
    vpc_security_group_ids               = [
        "sg-759f0a37",
    ]

    capacity_reservation_specification {
        capacity_reservation_preference = "open"
    }

    credit_specification {
        cpu_credits = "standard"
    }

    enclave_options {
        enabled = false
    }

    maintenance_options {
        auto_recovery = "default"
    }

    metadata_options {
        http_endpoint               = "enabled"
        http_put_response_hop_limit = 1
        http_tokens                 = "optional"
        instance_metadata_tags      = "disabled"
    }

    private_dns_name_options {
        enable_resource_name_dns_a_record    = false
        enable_resource_name_dns_aaaa_record = false
        hostname_type                        = "ip-name"
    }

    root_block_device {
        delete_on_termination = true
        device_name           = "/dev/xvda"
        encrypted             = false
        iops                  = 100
        tags                  = {}
        throughput            = 0
        volume_id             = "vol-026751c2ae22eb49d"
        volume_size           = 8
        volume_type           = "gp2"
    }
}

我们现在在这里提交吧。

顺便提一下,当想要更新配置时,可以使用 terraform apply 进行确认。

停止基础设施

如果想要停止已启动的资源,请执行↓

terraform destroy
Cursor_と_インスタンス___EC2_Management_Console.png

刚才正在启动的资源已经结束了。

传递变量

可以在 Terraform 的配置文件中传递变量,并且可以在每次命令执行时传递不同的值。

创建variables.tf,并按照下面的方式进行描述。

variable "instance_name" {
  description = "Value of the Name tag for the EC2 instance"
  type        = string
  default     = "ExampleAppServerInstance"
}

当将变量传递给设置文件时,请按照以下方式编写。

resource "aws_instance" "app_server" {
  ami           = "ami-078296f82eb463377"
  instance_type = "t2.micro"

  tags = {
    Name = var.instance_name
  }
}

如果使用var.instance_name,可以将名为instance_name的变量的值传递给tags的名称。

如果没有传递任何值,则默认情况下资源将以”default”的值启动,因为变量设置为 “ExampleAppServerInstance”。

順便提一下,可能是因为这里没有明确指定实例ID,所以刚才和现在启动的实例不同。(如果已经销毁过一次,会重新启动一个不同的资源吗?)

接下来在命令执行时传递变量。

terraform apply -var "instance_name=YetAnotherName"

这样做可以看到以下形式的日志,显示了Name的值已经变化。

Terraform will perform the following actions:

  # aws_instance.app_server will be updated in-place
  ~ resource "aws_instance" "app_server" {
        id                                   = "i-07106c4743876f6cb"
      ~ tags                                 = {
          ~ "Name" = "ExampleAppServerInstance" -> "YetAnotherName"
        }
      ~ tags_all                             = {
          ~ "Name" = "ExampleAppServerInstance" -> "YetAnotherName"
        }
        # (29 unchanged attributes hidden)

        # (7 unchanged blocks hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

我们可以在控制台上看到实际的数值已经发生变化。

Cursor_と_インスタンス___EC2_Management_Console.png

使其能够输出资源信息

使云计算基建工具Terraform通过命令行可验证所创建的资源。
这样一来,协作者可更方便地使用,也便于从AWS控制台中查找,具备一些优点。

创建 outputs.tf 文件,并按照以下方式进行描述。

output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.app_server.id
}

output "instance_public_ip" {
  description = "Public IP address of the EC2 instance"
  value       = aws_instance.app_server.public_ip
}

可以使用以下命令来确认设置内容。

terraform output

运行结果

tomolico@mourifuyusatorunoMacBook-Air learn-terraform-aws-instance % terraform output
instance_id = "i-07106c4743876f6cb"
instance_public_ip = "54.65.225.171"

将资源信息保存在 Terraform Cloud 中

可以将通过Terraform代码创建的资源信息存储在云端进行管理。看起来可以通过GUI界面进行查看,非常方便。

添加以下描述到 maim.tf

cloud {
    organization = "organization-name"
    workspaces {
      name = "learn-tfc-aws"
    }
  }

在组织中,当进行登录时需要进行设置。姓名可以使用任意的名称。

我們要將 CLI 和 Terraform Cloud 進行整合,執行下面的指令。

terraform login

因此,您需要在网页上输入生成的API令牌,就像下方所示。

Generate a token using your browser, and copy-paste it into this prompt.

Terraform will store the token in plain text in the following file
for use by subsequent commands:
    /Users/tomolico/.terraform.d/credentials.tfrc.json

Token for app.terraform.io:
  Enter a value: 
Cursor_と_Tokens___Account___Terraform_Cloud.png

顺便说一下,可以在网络上单独发行令牌。

如果尝试直接启动,会遇到以下错误。似乎需要通过环境变量传递AWS凭证。

Initializing plugins and modules...
╷
│ Error: error configuring Terraform AWS Provider: no valid credential sources for Terraform AWS Provider found.
│ 
│ Please see https://registry.terraform.io/providers/hashicorp/aws
│ for more information about providing credentials.
Cursor_と_Variables___aws-tutorial___moritania___Terraform_Cloud.png

在workspace的variables设置中进行配置并保存。顺便提一下,要进入这个页面需要先启动一个空的工作空间。可能当没有连接到云端时,默认会在命令行中读取已配置的环境变量,但是应该是由于与云端的连接而改变了读取位置。

顺便提一下,如果尝试直接启动实例,会出现类似下面的警告。

Changes to Outputs:
  + instance_id        = (known after apply)
  + instance_public_ip = (known after apply)
╷
│ Warning: Value for undeclared variable
│ 
│ The root module does not declare a variable named "AWS_SECRET_ACCESS_KEY"
│ but a value was found in file
│ "/home/tfc-agent/.tfc-agent/component/terraform/runs/run-ufJR9wYcwnidho6D/terraform.tfvars".
│ If you meant to use this value, add a "variable" block to the
│ configuration.
│ 
│ To silence these warnings, use TF_VAR_... environment variables to provide
│ certain "global" settings to all configurations in your organization. To
│ reduce the verbosity of these warnings, use the -compact-warnings option.
╵
╷
│ Warning: Value for undeclared variable
│ 
│ The root module does not declare a variable named "AWS_ACCESS_KEY_ID" but a
│ value was found in file
│ "/home/tfc-agent/.tfc-agent/component/terraform/runs/run-ufJR9wYcwnidho6D/terraform.tfvars".
│ If you meant to use this value, add a "variable" block to the
│ configuration.
│ 
│ To silence these warnings, use TF_VAR_... environment variables to provide
│ certain "global" settings to all configurations in your organization. To
│ reduce the verbosity of these warnings, use the -compact-warnings option.
╵

放置着也会运动,但是是否最好还是先从环境变量文件等读取比较好呢。

当在云端集成的情况下启动资源,会变得像↓这样的状态。这个比较清楚易懂,是吧。

Cursor_と_Overview___aws-tutorial___moritania___Terraform_Cloud.png

顺便提一下,当你终止资源时,会有以下显示。不可思议的是,它在命令行执行时以异步方式拉取给了我。太厉害了。

Cursor_と_Overview___aws-tutorial___moritania___Terraform_Cloud.png