Terraform,如何使用 salt-minion (masterless) 配置 droplet

Terraform,如何使用 salt-minion (masterless) 配置 droplet

我已经设法运行了一个本地开发服务器流浪汉,提供在一个无主配置。现在,我正在尝试利用现有的 salt states 来配置生产服务器,但到目前为止还没有弄清楚如何去做。

我已经成功创建了一个数字海洋水滴地形,现在我想为其提供,最好使用.sls与配置开发机器相同的文件。在 Vagrant 中,这相当简单,因为只需在 中声明它即可Vagrantfile,如下所示:

config.vm.provision :salt do |salt|
salt.minion_config = "salt/minion"
salt.run_highstate = true

之后,只需创建一个状态树指向我们的状态文件,在其中我们在其中声明我们希望为我们的机器配置的包、我们想要同步的文件等等。

然而Terraform,似乎没有类似的方法可以做到这一点。Terraform 的文档关于供应商的信息相当稀少。除了调用 Chef 客户端,或者直接在 上声明我们要复制的文件provisioner,或者调用脚本,我找不到任何关于如何调用 Salt 来配置实例的参考。我想知道这是否可能?

这是我的servers.tf

module "hosting" {
    source                  = "./modules/server"
    droplet_count           = 1
    droplet_image           = "ubuntu-14-04-x64"
    droplet_region          = "nyc2"
    droplet_size            = "512mb"       
    dns_record_domain       = "site.org"
    droplet_backups         = true
    droplet_ipv6            = true
    droplet_privatenet      = true
}

以下是我的droplet.tf文件:

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

resource "digitalocean_droplet" "droplet" {
    image           = "${var.droplet_image}"
    name            = "${var.droplet_type}-${format("%02d", count.index+1)}"
    region          = "${var.droplet_region}"
    size            = "${var.droplet_size}"
    ssh_keys        = ["${var.ssh_fingerprint}"]
    backups         = "${var.droplet_backups}"
    ipv6            = "${var.droplet_ipv6}"
    private_networking  = "${var.droplet_privatenet}"
}

resource "digitalocean_ssh_key" "default" {
    name            = "rsa-key-nopass"
    public_key      = "${file("./.ssh/rsa-key-nopass")}"
}

最后是我的dns_records.tf文件:

provider "cloudflare" {
    email   = "${var.cf_email}"
    token   = "${var.cf_token}" 
}

resource "cloudflare_record" "ipv4" {
    count   = "${var.droplet_count}"
    domain  = "${var.dns_record_domain}"
    name    = "${element(digitalocean_droplet.droplet.*.name, count.index)}"
    value   = "${element(digitalocean_droplet.droplet.*.ipv4_address, count.index)}"
    type    = "A"
    ttl     = 3600
}

resource "cloudflare_record" "ipv6" {
    count   = "${var.droplet_count}"
    domain  = "${var.dns_record_domain}"
    name    = "${element(digitalocean_droplet.droplet.*.name, count.index)}"
    value   = "${element(digitalocean_droplet.droplet.*.ipv6_address, count.index)}"
    type    = "AAAA"
    ttl     = 3600
}

提前感谢你的帮助!


更新

我添加了以下两个provisioner块:

provisioner "file" {
    source = "../salt"
    destination = "/etc/salt"
}

provisioner "remote-exec" {
    inline = [
      # install and configure salt-minion
      "curl -L https://bootstrap.saltstack.com -o install_salt.sh",
      "sudo sh install_salt.sh",
      "salt '*' state.apply"
    ]
}

目录/salt已成功复制/etc/salt,盐也已安装,但Script exited with non-zero exit status: 127在应用任何状态之前我收到了一条消息。具体原因我还不知道。

答案1

我发表了一篇例如,在 DigitalOcean 上使用 Terraform 设置 Salt Master,然后从那里启动一些 Minion。请注意,示例的某些部分假设 terraform 在 Windows 机器上启动(但不是下面列出的机器)。

来自saltmaster.tf

  1. 使用 terraform 将 SLS 文件复制到新服务器

    provisioner "file" {
        source = "master/srv"
        destination = "/"
    }
    
  2. 将启动文件复制到新服务器

    provisioner "file" {
        source = "complete-bootstrap.sh"
        destination = "/tmp/complete-bootstrap.sh"
    }
    

    complete-bootstrap.sh的内容:

    #!/bin/bash -x
    # create the minion's key pair and accept it on the master
    mkdir -p /etc/salt/pki/master/minions
    salt-key --gen-keys=minion --gen-keys-dir=/etc/salt/pki/minion
    mkdir -p /etc/salt/pki/minion
    cp /etc/salt/pki/minion/minion.pub /etc/salt/pki/master/minions/master
    service salt-master start
    salt-call -l debug state.highstate
    service salt-minion start
    
  3. 安装 salt minion 和 master

    provisioner "remote-exec" {
        inline = [
        # install salt-minion and salt-master, but don't start services
        "curl -L https://bootstrap.saltstack.com | sh -s -- -M -X -A localhost",
        # work around possible missing executable flag
        "cat /tmp/complete-bootstrap.sh | sh -s"
        ]
    }
    

这应该会让你在 DO 上从 Terraform 启动一个正在运行的 Salt Master。

答案2

告诉salt-minion在本地文件系统中查找状态树并运行我们salt-minionsalt-call命令似乎可以解决问题:

provisioner "remote-exec" {
    inline = [
    # install salt-minion
    "wget -O - http://bootstrap.saltstack.org | sudo sh"
    ]
}

provisioner "remote-exec" {
    inline = [
         # tell salt-minion to look for the state tree in 
         # the local file system, with the --local flag.
        "salt-call --local state.highstate"
    ]
}

minion文件中,告诉 salt 查看本地文件目录而不是salt master,这是默认配置(这将以无主模式运行 minion)。还需要将基础环境的根目录指向我们的 top.sls 所在的位置:

# Tell salt-minion to not look for a master. 
# Default configuration is file_client: remote

file_client: local

# Set the root directory for the base environment 
# to where our top.sls is located.

file_roots:
    base:
    - /etc/salt/roots

答案3

虽然这是一个老问题,但为了后人,我想提一下,我将 salt-masterless 供应器贡献给了 Terraform:

https://github.com/hashicorp/terraform/pull/14720

它已在 v0.10.2 版本中合并和部署。无论出于何种原因,该文档似乎尚未上传到网站,但您可以在此处访问原始文档文件:https://github.com/hashicorp/terraform/commit/08670763aa9b3f0a22ebf73f859f3b73a36351e2#diff-29ecd8bdf326c94e4f13d83497bc63e8

它的用法应该与 Packer salt-masterless provisioner 类似(由于声誉问题,我无法发布其他链接)。

这就是我最初复制代码的地方。

相关内容