标签: terraform

具有多个 Terraform 配置的有效 GitLab CI/CD 工作流程?

我的团队将 AWS 用于我们的基础设施,跨越 3 个不同的 AWS 账户。我们将简单地给他们打电话sandboxstagingproduction

我最近针对我们的 AWS 基础设施设置了 Terraform,它的层次结构映射到我们的帐户,然后是应用程序或 AWS 服务本身。回购结构看起来像这样:

staging
  iam
    groups
      main.tf
    users
      main.tf
  s3
    main.tf
sandbox
  iam
    ...
production
  applications
    gitlab
      main.tf
  route53
    main.tf
  ...
Run Code Online (Sandbox Code Playgroud)

我们为每个 AWS 服务(例如,IAM 或 S3)或应用程序(例如,GitLab)使用单独的配置,因此我们最终不会在.tf每个帐户中生成庞大的文件,这需要很长时间才能为任何一项更改应用更新。理想情况下,我们希望摆脱基于服务的配置方法,转向更多基于应用程序的配置,但无论哪种方式,手头的问题都是一样的。

当从命令行手动应用更新时,这种方法一直运行良好,但我很想将它移动到 GitLab CI/CD 以更好地自动化我们的工作流程,而这正是问题所在。

在我现有的设置中,如果我对,比如说,做一个单一的改变staging/s3/main.tf,GitLab 似乎没有一个开箱即用的好方法来只运行terraform planterraform apply用于特定的配置。

如果我改为将所有内容移动到main.tf整个 AWS 帐户的单个文件中(或多个文件但与单个状态文件相关联),我可以简单地让 GitLab 触发一个作业planapply仅触发该配置。根据我们在每个账户中拥有的 AWS 资源数量,运行可能需要 15 分钟,但我认为这是一个潜在的选择。

似乎我的问题最终可能与 GitLab 如何处理“monorepos”有关,而不是与 Terraform 如何处理其工作流程有关(毕竟,如果我只是告诉它 …

continuous-integration gitlab terraform

1
推荐指数
1
解决办法
2027
查看次数

在 Terraform 中使用创建的资源的最佳实践是什么?

我将在 AWS 上启动一个新的 Terraform 项目。VPC 已经创建,我想知道将它集成到我的代码中的最佳方式是什么。我是否必须再次创建它并且 Terraform 会检测到它并且不会覆盖它?或者我必须为此使用数据源吗?或者还有其他最好的方法,比如 Terraform Import ?

我还希望将来能够在其他区域或其他账户中部署整个基础设施。

谢谢。

vpc amazon-web-services terraform

1
推荐指数
1
解决办法
1539
查看次数

如何在子模块中使用远程状态数据源

我正在尝试从远程状态调用数据以引用网络 acl 的 vpc_id。当我运行计划/应用时,我收到错误“此对象没有参数、嵌套块或名为“vpc_id”的导出属性。

我试过使用“data.terraform_remote_state.*.vpc_id”以及“${}”语法。我尝试在子模块和父模块的 variables.tf 中定义 data.remote 信息。

我最终需要能够为不同的 VPC/子网动态调用这个模块。

相关的 VPC 已经存在,并且所有模块都已初始化。

s3 存储桶阶段/网络/vpc/terraform.tfstate:

"outputs": {
    "vpc_id": {
      "value": "vpc-1234567890",
      "type": "string"
    }
  },

enter code here
Run Code Online (Sandbox Code Playgroud)

模块/网络/acl/main.tf:

data "terraform_remote_state" "stage-network" {
  backend = "s3"

  config = {
    bucket          = "bucket"
    key             = "stage/network/vpc/terraform.tfstate"
  }
}

resource "aws_network_acl" "main" {
  vpc_id        = data.terraform_remote_state.stage-network.vpc_id
# acl variables here
Run Code Online (Sandbox Code Playgroud)

阶段/网络/acl/main.tf:

data "terraform_remote_state" "stage-network" {
  backend = "s3"

  config = {
    bucket          = "bucket"
    key             = "stage/network/vpc/terraform.tfstate"
  }
}

module "create_acl" …
Run Code Online (Sandbox Code Playgroud)

terraform terraform-provider-aws

1
推荐指数
1
解决办法
2546
查看次数

terraform 0.12 迁移后出现意外类型错误

我正在将我的 terraform 0.11 配置迁移到 terraform 0.12.5。

迁移(使用0.12upgrade)进行的比较顺利,但是后来我在下一个计划的时候遇到了这个错误

Error: Invalid value for module argument

  on main.tf line 72, in module "foo":
  72:   subnet_ids  = module.vpc.subnet_ids

The given value is not suitable for child module variable "subnet_ids"
defined at ../../modules/foo/main.tf:10,1-30: element 0: string
required.
Run Code Online (Sandbox Code Playgroud)

该模块foo有一个(迁移的)变量声明子网_ids,如下所示:

variable "subnet_ids" {
  type = list(string)
}
Run Code Online (Sandbox Code Playgroud)

vpc模块有一个输出声明,声明如下:

output "subnet_ids" {
  value = [aws_subnet.private.*.id]
}
Run Code Online (Sandbox Code Playgroud)

似乎如果我放松对foo模块的类型约束,错误就会消失。

然而,这是正确的做法。毕竟,vpc 模块的输出实际上不是一个字符串列表吗?如何检查 vpc 输出变量的类型?

更新:放宽类型约束允许验证的第一部分成功,但仅在根据此输出应用变量时对消费模块造成问题

Error: Incorrect attribute value type

  on ../../modules/foo/main.tf line 350, …
Run Code Online (Sandbox Code Playgroud)

module terraform

1
推荐指数
1
解决办法
2280
查看次数

Terraform:如何删除从数组/列表中创建的用户资源?

我有一个users.tf为 aws 创建管理员用户的文件。它通过定义一个列表(例如users = ["bob", "john", "tom"]

然后aws_iam_user使用countterraform 中的功能使用资源迭代它们,如下所示:

resource "aws_iam_user" "user" {
  count = length(local.users)
  name  = local.users[count.index]
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是,如果我删除数组的第一个元素(上面示例中的“bob”),那么 terraform 会建议在发出后执行的操作terraform plan,而不是删除 bob,是将 bob 更改为 john,将 john 更改为 tom ,并删除汤姆。

像这样:

  # aws_iam_user.user[0] will be updated in-place
  ~ resource "aws_iam_user" "user" {
        arn           = "arn:aws:iam::5555555:user/bob"
        force_destroy = false
        id            = "bob"
      ~ name          = "bob" -> "john"
        path          = "/"
        tags          = {}
        unique_id     = "BLABLABLA11111"
    }

  # …
Run Code Online (Sandbox Code Playgroud)

terraform

1
推荐指数
1
解决办法
1063
查看次数

为什么 terraform 会忽略手动创建的 s3 存储桶?

我发现我的 aws 帐户中有一个不是由 terraform 创建的存储桶。

我想确保它在我的 terraform 存储库中说明,但在我添加它之前,我运行terraform plan并得到以下响应:

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为当我跑步时,aws s3 ls我看到了桶:

#not real names from obvious reasons
2019-07-15 13:33:16 bucket-from-terrform
2019-07-15 13:19:26 terraform-state-bucket
2019-07-23 17:47:26 bucket-created-manually
Run Code Online (Sandbox Code Playgroud)

更重要的是,当我添加一个名称与之前忽略的存储桶匹配的资源时,terraform 会尝试添加它(即使它已经存在)

怎么了?terraform 忽略那个桶的原因可能是什么?

amazon-s3 terraform

1
推荐指数
1
解决办法
1790
查看次数

terraform 中 aws_launch_configuration 中的 source_dest_check

我希望从自动缩放启动配置中创建一个新启动的 ec2 实例,其中 source_dest_check = disabled(默认情况下已启用)。

我知道我们可以使用 source_dest_check = false 来创建 ec2 资源,但是如何在从 ASG 管理实例时实现相同的目标。

Terraform 不接受下面的 (source_dest_check = false) ,还有其他替代方法可以实现吗?

我可以从用户数据中实现这一点吗?

resource "aws_launch_configuration" "launchconfig" {
  name_prefix          = "bastion-"
  image_id             = "${data.aws_ami.amazon-linux-2.id}"
  instance_type        = "${var.instance_type}"
  placement_tenancy    = "default"
  enable_monitoring    = true
  #source_dest_check    = false
  security_groups      = ["${aws_security_group. security_group.id}"]
  iam_instance_profile = "${aws_iam_instance_profile.instance_profile.name}"
  key_name             = "${var. pem_key}"

  #Include user-data
  user_data = "${element(data.template_file.user_data.*.rendered, count.index)}"

  lifecycle {
    create_before_destroy = true
  }
}
Run Code Online (Sandbox Code Playgroud)

amazon-ec2 amazon-web-services boto3 terraform terraform-provider-aws

1
推荐指数
1
解决办法
1361
查看次数

Terraform 提供程序应如何处理应用于服务器端的默认值?

上下文:我正在实现(我的第一个)Terraform 插件/提供程序作为现有公共 API 的包装器。

API 中的创建操作之一指定了一个整数字段,该字段采用正值或-1作为默认值。如果您-1在 create API 调用中指定,该值将被服务器端的某个默认值替换(例如field = 1000),并1000从现在开始存储。

如果我将其呈现给我的 Terraform 插件 ( terraform apply):

resource "something" "mysomething" {
  name  = "someName"
  field = -1
}
Run Code Online (Sandbox Code Playgroud)

调用不是幂等的。Terraform 继续看到漂移,随后提供:

  # something.mysomething will be updated in-place
  ~ resource "something" "mysomething" {
        id               = "165-1567498530352"
        name             = "someName"
      ~ field            = 1000 -> -1
    }

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

如何处理这样的API?

go terraform

1
推荐指数
2
解决办法
666
查看次数

EKS kube 系统部署 CrashLoopBackOff

我正在尝试将 Kube 状态指标部署到kube-system运行 Kubernetes v1.14 的 EKS 集群 (eks.4) 中的命名空间中。

Kubernetes 连接

provider "kubernetes" {
  host                   = var.cluster.endpoint
  token                  = data.aws_eks_cluster_auth.cluster_auth.token
  cluster_ca_certificate = base64decode(var.cluster.certificate)
  load_config_file       = true
}
Run Code Online (Sandbox Code Playgroud)

部署清单(作为 .tf)

resource "kubernetes_deployment" "kube_state_metrics" {
  metadata {
    name      = "kube-state-metrics"
    namespace = "kube-system"

    labels = {
      k8s-app = "kube-state-metrics"
    }
  }

  spec {
    replicas = 1

    selector {
      match_labels = {
        k8s-app = "kube-state-metrics"
      }
    }

    template {
      metadata {
        labels = {
          k8s-app = "kube-state-metrics"
        }
      }

      spec …
Run Code Online (Sandbox Code Playgroud)

kubernetes terraform amazon-eks

1
推荐指数
1
解决办法
1046
查看次数

terraform v0.12.12 在模块之间传递数据 - 这应该如何工作?

我正在努力理解数据在 Terraform (v0.12.12) 中传入和传出模块的方式。我有一个我认为非常简单的例子,但无法理解数据应该如何在模块之间传递。我能找到的大多数例子要么不完整,要么过时。

我创建了一个包含两个模块的简单示例。创建 vpc 和子网的网络模块,以及创建 EC2 实例的计算模块。我只是想为计算模块提供 EC2 实例应该去的子网的 ID。但我不明白:

  1. 如何从创建子网的网络模块中获取子网 ID 以便其他模块可以使用它?
  2. 如何让计算模块使用 subnet_id ?

基本结构如下

. ??? main.tf ??? modules ??? compute ? ??? main.tf ??? network ??? main.tf ??? output.tf

# main.tf
provider "aws" {
    region     = "eu-west-1"
}

module "m_network" {
    source      = "./modules/network"
}

# The problem is how to make that subnet id available to the compute module
# so the ec2 instance can be added to it? 
module "m_compute" {
    source …
Run Code Online (Sandbox Code Playgroud)

module output terraform

1
推荐指数
1
解决办法
990
查看次数