如何使用Terraform与DigitalOcean

Terraform是有组织地构建和管理基础设施的工具。它可以被用来管理DigitalOceanDroplet和DNS条目,除了大量的各种由其他供应商提供的服务。它通过一个易于使用的命令行界面控制,可以从您的桌面或远程服务器上运行。 通过读取描述组成应用环境或数据中心的组件配置文件Terraform作品...

介绍

Terraform是一种有组织地建设和管理基础设施的工具。 它可以用于管理DigitalOceanDroplet和DNS条目,以及其他提供商提供的大量服务。 它通过易于使用的命令行界面进行控制,并且可以从桌面或远程服务器运行。

Terraform通过读取描述组成应用程序环境或数据中心的组件的配置文件来工作。 基于配置,它生成一个执行计划,它描述了它将如何达到所需的状态。 然后执行该计划以构建基础设施。 当发生配置更改时,Terraform可以生成和执行增量计划,将现有基础架构更新到新描述的状态。

在本教程中,我们将演示如何使用Terraform创建一个简单的基础设施,由两台由HAProxy服务器负载平衡的Nginx服务器组成(见下图)。 这将帮助您开始使用Terraform,并且了解如何使用它来管理和部署基于DigitalOcean的基础设施,以满足您自己的需求。

示例基础结构

让我们来看看你需要遵循本教程。

先决条件

DigitalOcean帐户

因为本教程的重点是使用Terraform的DigitalOcean提供程序,您需要有一个有效的DigitalOcean帐户。 如果您还没有一个, 在这里注册

DigitalOcean API令牌

通过DigitalOcean控制面板生成个人访问令牌。 :说明这样做可以在这个链接找到如何生成个人访问令牌

在您将运行Terraform的每个终端中,导出您的DigitalOcean个人访问令牌:

export DO_PAT={YOUR_PERSONAL_ACCESS_TOKEN}

Terraform将使用此令牌对DigitalOcean API进行身份验证,并控制您的帐户。 保持此私有!

向DigitalOcean Cloud添加无密码SSH密钥

如果您尚未添加一个无密码SSH密钥到你的帐户DigitalOcean,按照这样做的这个教程

假设你的私钥位于~/.ssh/id_rsa ,请使用以下命令来获取您的公共密钥的指纹:

ssh-keygen -lf ~/.ssh/id_rsa.pub | awk '{print $2}'

这将输出如下:

e7:42:16:d7:e5:a0:43:29:82:7d:a0:59:cf:9e:92:f7

您需要在运行Terraform时提供此指纹,如此(将所有高亮显示的字词替换为适当的值):

terraform plan \
  -var "do_token=${DO_PAT}" \
  -var "pub_key=$HOME/.ssh/id_rsa.pub" \
  -var "pvt_key=$HOME/.ssh/id_rsa" \
  -var "ssh_fingerprint=e7:42:16:d7:e5:a0:43:29:82:7d:a0:59:cf:9e:92:f7"

为了让事情变得更容易,你可能需要设置$ SSH_FINGERPRINT使用下面的命令:

export SSH_FINGERPRINT=$(ssh-keygen -lf ~/.ssh/id_rsa.pub | awk '{print $2}')

现在我们已经有了前提条件,让我们安装Terraform!

安装Terraform

注:本教程采用的Terraform 0.1.1写的。

Terraform非常容易安装,可以在桌面或远程服务器上运行。 这里是步骤:

1.下载Terraform

下载相应的包为您的操作系统和架构: 下载Terraform

2.提取Terraform

将您刚刚下载的软件包解压缩到您选择的目录中。

如果你把它下载到~/Downloads ,您可以运行以下命令解压:

mkdir -p ~/opt/terraform
unzip ~/Downloads/terraform_0.1.1_darwin_amd64.zip -d ~/opt/terraform

这解档包到opt/terraform/目录下,你的home目录中。

3.添加配置文件的路径

最后一步是添加Terraform的bin目录, ~/opt/terraform/bin ,到PATH环境变量以便于访问。

例如,如果你使用bash作为你的shell,你可以在路径添加到您的.bash_profile 打开您的个人资料进行编辑:

vi ~/.bash_profile

要将Terraform的路径附加到PATH,请在文件末尾添加以下行:

export PATH=$PATH:~/opt/terraform/bin

保存并退出。

现在,所有新的bash会话就能找到terraform命令。 如果要将新的PATH加载到当前会话中,请键入以下内容:

. .bash_profile

验证Terraform安装

要验证您是否正确安装Terraform,让我们尝试并运行它。 在终端中,运行Terraform:

terraform

如果您的路径设置正确,您将看到类似于以下内容的输出:

Available commands are:
    apply      Builds or changes infrastructure
    graph      Create a visual graph of Terraform resources
    output     Read an output from a state file
    plan       Generate and show an execution plan
    refresh    Update local state file against real resources
    show       Inspect Terraform state or plan
    version    Prints the Terraform version

这些是Terraform接受的命令。 他们的简介在这里描述,但我们将进入如何使用它们。

现在Terraform已经安装,让我们开始写一个配置来描述我们的基础设施!

创建配置目录

使用Terraform构建基础架构的第一步是创建一个目录,存储给定项目的配置文件。 目录的名称无关紧要,但我们将使用“loadbalance”作为示例(可随意更改其名称):

mkdir ~/loadbalance

Terraform配置是与最终文本文件.tf文件扩展名。 他们是人类可读的,他们支持评论。 Terraform还支持JSON格式的配置文件,但我们不会在这里讨论。 Terraform将以声明方式读取工作目录中的所有配置文件,因此资源和变量定义的顺序无关紧要。 您的整个基础架构可以存在于单个配置文件中,但我们将在本教程中按资源分隔我们的配置文件。

将当前目录更改为新创建的目录:

cd ~/loadbalance

从现在开始,我们将假设您的工作目录是我们刚才改变的目录。 如果启动新的终端会话,请务必切换到包含Terraform配置的目录。

如果你被卡住

如果你碰巧遇到问题,正如你期望Terraform不工作,你可以通过删除从头再来terraform.tfstate (通过控制面板或者像另一个API工具如文件,手动消灭创建的资源拖轮 )。

您可能还需要启用日志记录到stdout,以便您可以看到Terraform正在尝试做什么。 通过运行以下命令来执行此操作:

export TF_LOG=1

另外,如果你无法构建有效的配置,完整的配置文件在以下GitHub的要点可供选择: 配置文件

让我们继续创建Terraform配置。

创建提供程序配置

Terraform通过其提供的“提供商”支持各种服务提供商。 我们对DigitalOcean提供商感兴趣,Terraform将使用它与DigitalOcean API进行交互以构建我们的基础设施。 使用DigitalOcean提供程序的第一步是使用适当的凭据变量配置它。 让我们现在做。

创建一个文件名为provider.tf

vi provider.tf

将以下行添加到文件中:

variable "do_token" {}
variable "pub_key" {}
variable "pvt_key" {}
variable "ssh_fingerprint" {}

provider "digitalocean" {
  token = "${var.do_token}"
}

保存并退出。 下面是前四行的细分:

  • 变量“do_token”:你个人DigitalOcean访问令牌
  • 变量“pub_key”:公开密钥的位置,因此它可以被安装到新的Droplet
  • 变量“pvt_key”:私有密钥的位置,所以Terraform可以连接到新的Droplet
  • 变量“ssh_fingerprint”:SSH密钥指纹

下面的几行通过分配“令牌”的do_token变量指定您DigitalOcean帐户的凭据。 当我们运行它们时,我们将把这些变量的值传递给Terraform。

在DigitalOcean提供的官方文档Terraform位于这里: DigitalOcean提供商

数字海洋资源

每个提供者具有其自己的规范,其通常映射到其相应服务提供商的API。 在DigitalOcean提供商的情况下,我们能够定义三种类型的资源:

  • digitalocean_domain:DNS域条目
  • digitalocean_droplet:Droplet(即VPS或服务器)
  • digitalocean_record:DNS记录

让我们开始创建一个将运行Nginx服务器的Droplet。

描述第一个Nginx服务器

创建一个新的名为Terraform配置文件www-1.tf

vi www-1.tf

插入以下行以定义Droplet资源:

resource "digitalocean_droplet" "www-1" {
    image = "ubuntu-14-04-x64"
    name = "www-1"
    region = "nyc2"
    size = "512mb"
    private_networking = true
    ssh_keys = [
      "${var.ssh_fingerprint}"
    ]

在上述结构中,第一行定义了一个名为“WWW-1”的digitalocean_droplet资源。 其余的行指定了Droplet的属性,可以通过DigitalOcean API访问。 一切都是不言自明的,所以我们不会解释每一行。 此外,Terraform将收集有关Droplet的各种信息,例如其公共和专用IP地址,可供您的配置中的其他资源使用。

如果你想知道哪些是必需的或可选的Droplet资源参数,请参考官方Terraform文档: DigitalOceanDroplet规格

现在,我们将建立一个connection这Terraform可以使用通过SSH连接到服务器。 在文件末尾插入以下行:

  connection {
      user = "root"
      type = "ssh"
      key_file = "${var.pvt_key}"
      timeout = "2m"
  }

上面的行描述了Terraform应该如何连接到服务器,以防我们想通过SSH来配置任何东西(注意使用私钥变量)。

现在我们已经建立了连接,我们可以配置“remote-exec”供应商。 我们将使用remote-exec provisioninger来安装Nginx。 将以下行添加到配置中:

  provisioner "remote-exec" {
    inline = [
      "export PATH=$PATH:/usr/bin",
      # install nginx
      "sudo apt-get update",
      "sudo apt-get -y install nginx"
    ]
  }
}

保存并退出。

需要注意的是内联数组中的字符串是将运行以安装Nginx的命令。

运行Terraform创建Nginx服务器

目前,您的Terraform配置描述单个Nginx服务器。 让我们测试一下。

运行以下terraform plan的命令,看看有什么Terraform将尝试做打造您所描述的基础设施(即见的执行计划)。 您必须指定下面列出的所有变量的值:

terraform plan \
  -var "do_token=${DO_PAT}" \
  -var "pub_key=$HOME/.ssh/id_rsa.pub" \
  -var "pvt_key=$HOME/.ssh/id_rsa" \
  -var "ssh_fingerprint=$SSH_FINGERPRINT"

如果所有变量设置正确,您应该看到几行输出,包括以下行:

Refreshing Terraform state prior to plan...
...
+ digitalocean_droplet.www-1
...

绿色+ digitalocean_droplet.www-1线意味着Terraform将创建一个名为“WWW-1”的新Droplet的资源,与它后面的细节。 这正是我们想要的,所以让我们执行计划。 运行以下terraform apply命令来执行目前的计划。 再次,指定以下变量的所有值:

terraform apply \
  -var "do_token=${DO_PAT}" \
  -var "pub_key=$HOME/.ssh/id_rsa.pub" \
  -var "pvt_key=$HOME/.ssh/id_rsa" \
  -var "ssh_fingerprint=$SSH_FINGERPRINT"

您应该看到包含以下行的输出(为了简洁而截断):

digitalocean_droplet.www-1: Creating...
...

digitalocean_droplet.www-1: Provisioning with 'remote-exec'...
digitalocean_droplet.www-1: Creation complete

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
...

在这一点上,Terraform创建了一个名为www-1的新Droplet,并在其上安装了Nginx。 如果您访问www-1的公共IP地址,您应该会看到一个Nginx欢迎屏幕。

描述第二个Nginx服务器

现在你已经描述了一个Nginx服务器,很容易添加第二个。 让我们复制原始配置文件并替换Droplet资源的名称(和主机名)。

您可以手动做到这一点,或使用sed替代“WWW-1”的所有实例以“WWW-2”(有两个),并创建一个新的文件。 这里是sed命令这样做:

sed 's/www-1/www-2/g' www-1.tf > www-2.tf

现在,如果你运行terraform planterraform apply再次,它会显示或分别执行新的计划。 因为我们已经知道Terraform只会创建另一个NginxDroplet,让我们保存为以后。

现在让我们配置我们的HAProxyDroplet。

描述HAProxy Server

创建一个新的名为Terraform配置文件haproxy-www.tf

vi haproxy-www.tf

插入以下行以描述新Droplet。 第一部分与NginxDroplet描述相同,除了它具有不同的名称“haproxy-www”:

resource "digitalocean_droplet" "haproxy-www" {
    image = "ubuntu-14-04-x64"
    name = "haproxy-www"
    region = "nyc2"
    size = "512mb"
    private_networking = true
    ssh_keys = [
      "${var.ssh_fingerprint}"
    ]

插入以下连接信息(再次,与NginxDroplet相同):

  connection {
      user = "root"
      type = "ssh"
      key_file = "${var.pvt_key}"
      timeout = "2m"
  }

现在我们已经建立了连接,我们可以配置“remote-exec”供应商。 我们将使用remote-exec设置程序来安装和配置HAProxy。 将以下行添加到配置中:

  provisioner "remote-exec" {
    inline = [
      "export PATH=$PATH:/usr/bin",
      # install haproxy 1.5
      "sudo add-apt-repository -y ppa:vbernat/haproxy-1.5",
      "sudo apt-get update",
      "sudo apt-get -y install haproxy",

      # download haproxy conf
      "sudo wget https://gist.githubusercontent.com/thisismitch/91815a582c27bd8aa44d/raw/8fc59b7cb88a2be9b802cd76288ca1c2ea957dd9/haproxy.cfg -O /etc/haproxy/haproxy.cfg",

      # replace ip address variables in haproxy conf to use droplet ip addresses
      "sudo sed -i 's/HAPROXY_PUBLIC_IP/${digitalocean_droplet.haproxy-www.ipv4_address}/g' /etc/haproxy/haproxy.cfg",
      "sudo sed -i 's/WWW_1_PRIVATE_IP/${digitalocean_droplet.www-1.ipv4_address_private}/g' /etc/haproxy/haproxy.cfg",
      "sudo sed -i 's/WWW_2_PRIVATE_IP/${digitalocean_droplet.www-2.ipv4_address_private}/g' /etc/haproxy/haproxy.cfg",

      # restart haproxy to load changes
      "sudo service haproxy restart"
    ]
  }
}

保存并退出。

再次, 内联数组中的字符串是根将运行来安装和配置HAProxy的命令。 安装HAProxy的后,一个样品haproxy.cfg文件被下载。 在这一点上, sed命令替换某些字符串与每个Droplet的相应的IP地址HAProxy的配置文件中,通过使用Terraform变量(在上面红色高亮显示),从而为它配置的HAProxy的将准备尽快运行。 最后,重新启动HAProxy以加载配置更改。

从更实际的情况下,你可能也有Terraform系统,你可以复制到您的服务器的“文件”置备对自己haproxy.cfg文件。

我们的HAProxy服务器现在描述,但我们必须运行Terraform才能构建它。

运行Terraform创建HAProxy服务器

目前,您的Terraform配置描述了两个Nginx服务器和一个HAProxy服务器。 让我们

运行terraform plan再次命令来查看新的执行计划:

terraform plan \
  -var "do_token=${DO_PAT}" \
  -var "pub_key=$HOME/.ssh/id_rsa.pub" \
  -var "pvt_key=$HOME/.ssh/id_rsa" \
  -var "ssh_fingerprint=$SSH_FINGERPRINT"

您应该看到几行输出,包括以下行:

...
digitalocean_droplet.www-1: Refreshing state... (ID: 2236747)
...
+ digitalocean_droplet.haproxy-www
...
+ digitalocean_droplet.www-2
...

这意味着,在WWW 1Droplet已经存在,发展和terraform将创建的haproxy-wwwWWW的2Droplet。 让我们运行terraform apply构建其余组件:

terraform apply \
  -var "do_token=${DO_PAT}" \
  -var "pub_key=$HOME/.ssh/id_rsa.pub" \
  -var "pvt_key=$HOME/.ssh/id_rsa" \
  -var "ssh_fingerprint=$SSH_FINGERPRINT"

您应该看到包含以下行的输出(为了简洁而截断):

digitalocean_droplet.www-2: Creating...
...
digitalocean_droplet.www-2: Provisioning with 'remote-exec'...
digitalocean_droplet.www-2: Creation complete
...
digitalocean_droplet.haproxy-www: Creating...
...
digitalocean_droplet.haproxy-www: Provisioning with 'remote-exec'...
digitalocean_droplet.haproxy-www: Creation complete
...
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
...

此时,Terraform已经创建了一个新的Nginx服务器和HAProxy服务器。 如果您访问haproxy-www的公共IP地址,您应该会看到一个Nginx欢迎屏幕(因为HAProxy负载平衡两个Nginx服务器)。

你设置完成!本教程的其余部分包括关于如何使用其他Terraform命令配置DNS域和Terraform记录资源和信息。

创建DNS域和记录

如前所述,Terraform还可以创建DNS域和记录域。 例如,如果您想您的域名指向example.com到新创建的HAProxy的服务器,你可以创建为Terraform配置注:使用你自己的,独特的,域名或这一步会失败,因为(即不使用“ example.com“或DigitalOcean DNS中已存在的任何其他记录)

创建一个新文件来描述您的DNS:

vi example.com

插入以下域资源:

# Create a new domain record
resource "digitalocean_domain" "default" {
   name = "example.com"
   ip_address = "${digitalocean_droplet.haproxy-www.ipv4_address}"
}

虽然我们在这,让我们添加一个指向CNAME记录“WWW .example.com的”到“example.com”:

resource "digitalocean_record" "CNAME-www" {
  domain = "${digitalocean_domain.default.name}"
  type = "CNAME"
  name = "www"
  value = "@"
}

保存并退出。

要添加DNS条目,运行terraform plan之后terraform apply ,与其他资源。

其他Terraform命令

Terraform有几个其他命令,以前没有覆盖,所以我们将在这里讨论他们中的大多数。

显示状态

Terraform每次执行计划或“刷新”状态时更新状态文件。 请注意,如果您修改Terraform之外的基础架构,您的状态文件将过期。

要查看环境的当前状态,请使用以下命令:

terraform show terraform.tfstate

刷新状态

如果您的资源在Terraform之外修改,您可以刷新状态文件以使其更新。 此命令将从提供程序拉取更新的资源信息:

terraform refresh \
  -var "do_token=${DO_PAT}" \
  -var "pub_key=$HOME/.ssh/id_rsa.pub" \
  -var "pvt_key=$HOME/.ssh/id_rsa" \
  -var "ssh_fingerprint=$SSH_FINGERPRINT"

破坏基础设施

虽然不常用于生产环境,Terraform也可以破坏它创建的基础设施。 这主要在多次构建和销毁的开发环境中有用。 这是一个两步的过程,下面描述。

1.创建一个执行计划来销毁基础设施:

terraform plan -destroy -out=terraform.tfplan \
  -var "do_token=${DO_PAT}" \
  -var "pub_key=$HOME/.ssh/id_rsa.pub" \
  -var "pvt_key=$HOME/.ssh/id_rsa" \
  -var "ssh_fingerprint=$SSH_FINGERPRINT"

Terraform将输出一个计划,其资源标记为红色,并带有减号,表示它将删除基础架构中的资源。

2.应用destroy:

terraform apply terraform.tfplan

Terraform将破坏资源,如破坏计划中所示。

结论

现在,您已了解Terraform的工作原理,随时可以创建描述对您有用的服务器基础架构的配置文件。 示例设置很简单,但演示了自动部署服务器有多么容易。 如果已经使用配置管理工具(如Puppet或Chef),则可以调用具有Terraform配置程序的配置管理工具,以将服务器配置为其创建过程的一部分。

Terraform有更多的功能,并可以与其他提供商。 退房的官方Terraform文档 ,详细了解如何使用Terraform来改善自己的基础设施。