我制作了一个Terraform脚本,该脚本可以成功启动2个DigitalOcean小滴作为节点,并在其中一个安装Kubernetes主节点,在另一个安装工人。
为此,它使用bash shell环境变量,其定义为:
export DO_ACCESS_TOKEN="..."
export TF_VAR_DO_ACCESS_TOKEN=$DO_ACCESS_TOKEN
然后可以在脚本中使用它:
provider "digitalocean" {
version = "~> 1.0"
token = "${var.DO_ACCESS_TOKEN}"
}
现在,所有这些文件都放在一个目录中,变得有些混乱。因此,我正在尝试将其实现为模块。
因此,我有一个provider
模块可以访问我的DigitalOcean帐户,一个droplet
模块可以旋转一个具有给定名称的液滴,一个Kubernetes master
模块和一个{{1 }}模块。
我可以运行Kubernetes worker
命令。
但是在运行terraform init
命令时,它会要求我提供提供者令牌(在实现模块之前,它没有做过):
terraform plan
似乎找不到在bash shell环境中定义的令牌。
我有以下模块:
$ terraform plan
provider.digitalocean.token
The token key for API operations.
Enter a value:
在我的项目目录中,我有一个.
├── digitalocean
│ ├── droplet
│ │ ├── create-ssh-key-certificate.sh
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ └── vars.tf
│ └── provider
│ ├── main.tf
│ └── vars.tf
└── kubernetes
├── master
│ ├── configure-cluster.sh
│ ├── configure-user.sh
│ ├── create-namespace.sh
│ ├── create-role-binding-deployment-manager.yml
│ ├── create-role-deployment-manager.yml
│ ├── kubernetes-bootstrap.sh
│ ├── main.tf
│ ├── outputs.tf
│ └── vars.tf
└── worker
├── kubernetes-bootstrap.sh
├── main.tf
├── outputs.tf
└── vars.tf
文件:
vars.tf
我有一个$ cat vars.tf
variable "DO_ACCESS_TOKEN" {}
variable "SSH_PUBLIC_KEY" {}
variable "SSH_PRIVATE_KEY" {}
variable "SSH_FINGERPRINT" {}
文件:
provider.tf
它调用$ cat provider.tf
module "digitalocean" {
source = "/home/stephane/dev/terraform/modules/digitalocean/provider"
DO_ACCESS_TOKEN = "${var.DO_ACCESS_TOKEN}"
}
模块,其定义为:
digitalocean provider
更新:提供的解决方案使我可以像这样组织我的项目:
$ cat digitalocean/provider/vars.tf
variable "DO_ACCESS_TOKEN" {}
$ cat digitalocean/provider/main.tf
provider "digitalocean" {
version = "~> 1.0"
token = "${var.DO_ACCESS_TOKEN}"
}
具有自定义的提供程序,堆栈和模块库,其分层方式如下:
.
├── env
│ ├── dev
│ │ ├── backend.tf -> /home/stephane/dev/terraform/utils/backend.tf
│ │ ├── digital-ocean.tf -> /home/stephane/dev/terraform/providers/digital-ocean.tf
│ │ ├── kubernetes-master.tf -> /home/stephane/dev/terraform/stacks/kubernetes-master.tf
│ │ ├── kubernetes-worker-1.tf -> /home/stephane/dev/terraform/stacks/kubernetes-worker-1.tf
│ │ ├── outputs.tf -> /home/stephane/dev/terraform/stacks/outputs.tf
│ │ ├── terraform.tfplan
│ │ ├── terraform.tfstate
│ │ ├── terraform.tfstate.backup
│ │ ├── terraform.tfvars
│ │ └── vars.tf -> /home/stephane/dev/terraform/utils/vars.tf
│ ├── production
│ └── staging
└── README.md
答案 0 :(得分:2)
这里最简单的选择是根本不定义提供程序,而仅使用Digital Ocean提供程序文档中提到的DIGITALOCEAN_TOKEN
环境变量。
这将始终使用最新版本的Digital Ocean提供程序,但在功能上与您当前正在执行的操作相同。
但是,如果您确实想要定义provider块,以便可以指定所使用的provider的版本,或者也可以借此机会定义部分状态配置或设置所需的Terraform版本,则只需确保提供程序定义的文件位于您要应用的同一目录中或位于源模块中(如果您正在执行部分状态配置,则它们必须位于目录中,而不是模块中,因为在获取模块之前会进行状态配置)。
通常,我只需在要应用Terraform代码的所有位置(所以不仅是模块的所有位置)之间符号链接我的提供程序文件即可实现此目的。
作为示例,您可能具有一个类似于以下内容的目录结构:
.
├── modules
│ └── kubernetes
│ ├── master
│ │ ├── main.tf
│ │ ├── output.tf
│ │ └── variables.tf
│ └── worker
│ ├── main.tf
│ ├── output.tf
│ └── variables.tf
├── production
│ ├── digital-ocean.tf -> ../providers/digital-ocean.tf
│ ├── kubernetes-master.tf -> ../stacks/kubernetes-master.tf
│ ├── kubernetes-worker.tf -> ../stacks/kubernetes-worker.tf
│ └── terraform.tfvars
├── providers
│ └── digital-ocean.tf
├── stacks
│ ├── kubernetes-master.tf
│ └── kubernetes-worker.tf
└── staging
├── digital-ocean.tf -> ../providers/digital-ocean.tf
├── kubernetes-master.tf -> ../stacks/kubernetes-master.tf
├── kubernetes-worker.tf -> ../stacks/kubernetes-worker.tf
└── terraform.tfvars
此布局有2个“位置”,您可以在这些位置执行Terraform动作(例如plan
/ apply
):登台和生产(作为示例,使内容尽可能相似,并且环境)。除了terraform.tfvars
文件之外,这些目录仅包含符号链接文件,该文件允许您仅更改一些受约束的内容,从而使暂存和生产环境保持不变。
符号链接的提供程序文件将包含任何特定于提供程序的配置(对于AWS,通常将包括应在其中创建内容的区域,对于Digital Ocean,这可能只是限制应提供程序的版本。使用),但也可以包含部分Terraform状态配置,以最小化在运行terraform init
甚至只是设置所需的Terraform版本时需要通过的配置。一个例子可能看起来像这样:
provider "digitalocean" {
version = "~> 1.0"
}
terraform {
required_version = "=0.11.10"
backend "s3" {
region = "eu-west-1"
encrypt = true
kms_key_id = "alias/terraform-state"
dynamodb_table = "terraform-locks"
}
}