标签: terraform

将 GitLab CI 变量注入 Terraform 变量

我有一组 Terraform 文件,特别是一个 Variables.tf 文件,它保存了我的变量,如 aws 访问密钥、aws 访问令牌等。我现在想使用 GitLab CI / CD 在 AWS 上自动创建资源。

我的计划如下:

  1. 编写 .gitlab-ci-yml 文件

  2. 在 .gitlab-ci.yml 文件中进行 terraform 调用

我知道我可以在 GitLab 中拥有秘密环境变量,但我不确定如何将这些变量推送到我的 Terraform Variables.tf 文件中,现在看起来像这样!

# AWS Config

variable "aws_access_key" {
  default = "YOUR_ADMIN_ACCESS_KEY"
}

variable "aws_secret_key" {
  default = "YOUR_ADMIN_SECRET_KEY"
}

variable "aws_region" {
  default = "us-west-2"
}
Run Code Online (Sandbox Code Playgroud)

在我的 .gitlab-ci.yml 中,我可以访问如下秘密:

- 'AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}' 
- 'AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}' 
- 'AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION}'
Run Code Online (Sandbox Code Playgroud)

如何将其传送到我的 Terraform 脚本?有任何想法吗?我需要从 GitLab 环境中读取秘密并将其传递给 Terraform 脚本!

continuous-integration amazon-web-services gitlab terraform

12
推荐指数
2
解决办法
3万
查看次数

在 Terraform 0.12 中连接两个列表 - concat()

我想在 Terraform 0.12 中连接两个数组。在我的示例中,有公共和私有子网。我想将它们分配给相同的网络访问列表。以下代码缩短:

data "aws_subnet_ids" "private" {
    vpc_id = aws_vpc.main.id
    tags = {
        subnet-type  = "private"
    }
}

data "aws_subnet_ids" "public" {
    vpc_id = aws_vpc.main.id
    tags = {
        subnet-type  = "public"
    }
}


resource "aws_network_acl" "networks" {
    vpc_id = aws_vpc.main.id

    subnet_ids = concat(data.aws_subnet_ids.private.ids, data.aws_subnet_ids.public.ids)
    [...]
}
Run Code Online (Sandbox Code Playgroud)

如果我使用以下输出:

output "private_subnets" {
  value = data.aws_subnet_ids.private.ids
}

output "public_subnets" {
  value = data.aws_subnet_ids.public.ids
}
Run Code Online (Sandbox Code Playgroud)

生成以下输出:

private_subnets = [
  "subnet-243zr427rhhfjseb9",
  "subnet-we789rh2438fchb6e",
  "subnet-092rz7g82fhhkui74",
]
public_subnets = [
  "subnet-12230qegvg764e9d",
  "subnet-123465svgvgf0d7e",
]
Run Code Online (Sandbox Code Playgroud)

所以一切都应该有效。但是给出了以下错误:

iptizer@machine:~/src/infra$ terraform12 apply …
Run Code Online (Sandbox Code Playgroud)

terraform

12
推荐指数
2
解决办法
2万
查看次数

Terraform 因无效的 for_each 参数而失败/给定的“for_each”参数值不合适

运行时terraform planterraform apply使用提供给for_each错误的列表时,说

Error: Invalid for_each argument

  on main.tf line 2, in resource "aws_ssm_parameter" "foo":
  2:   for_each = ["a", "b"]

The given "for_each" argument value is unsuitable: the "for_each" argument
must be a map, or set of strings, and you have provided a value of type tuple.
Run Code Online (Sandbox Code Playgroud)

重现此错误的最小示例如下:

resource "aws_ssm_parameter" "foo" {
  for_each = ["a", "b"]

  name  = "foo-${each.value}"
  type  = "String"
  value = "bar-${each.value}"
}
Run Code Online (Sandbox Code Playgroud)

foreach amazon-web-services terraform

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

Terraform AWS EKS ALB Kubernetes Ingress 不会创建侦听器或目标组

我正在尝试使用 Terraform 资源创建一个带有 ALB 入口的 AWS EKS 集群。

该文档表明入口将自动创建一个带有关联侦听器和目标组的负载均衡器。

Kubernetes Ingress 创建 ALB 负载均衡器、安全组和规则,但不创建目标组或侦听器。我曾尝试使用网关或应用程序子网,但没有任何区别。我尝试设置安全组,但 ALB 设置并使用了它自己的自我管理的安全组。

我依赖本指南

ALB 的卷曲让我感到

无法连接到 de59ecbf-default-mainingre-8687-1051686593.ap-southeast-1.elb.amazonaws.com 端口 80:连接被拒绝

我分别创建了 IAM 角色和 ACM 证书,因为 AWS 对这些有配额限制。我的 EKS 集群和节点角色是标准的,节点角色附加了最新的策略。

我曾经kubectl单独应用 kubernetes 入口,但结果相同。它创建 ALB 和一个安全组,其中包含端口规则,但没有目标组或侦听器。

当我将集群端点粘贴aws eks describe-cluster --name my-tf-eks-cluster --query "cluster.endpoint"到浏览器中时,我得到以下信息:

{ "kind": "Status", "apiVersion": "v1", "metadata": { }, "status": "Failure", "message": "forbidden: User "system:anonymous" cannot get path "/ "", "reason": "Forbidden", "details": { }, "code": 403 }

此外,入口没有 IP 地址。 …

terraform kubernetes-ingress terraform-provider-aws amazon-eks

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

Terraform:googleapi:错误 403:资源项目的权限被拒绝

googleapi:错误403:资源项目shared_vpc_host_name的权限被拒绝。,禁止

我正在尝试使用 Terraform 项目 facotry 模块创建共享 vpc 和服务项目,但我遇到了错误,不确定它是否真的与权限相关。这是我收到的错误

Error: googleapi: Error 403: Permission denied on resource project shared_vpc_host_name., forbidden

on .terraform/modules/project_factory/terraform-google-project-factory-8.1.0/modules/core_project_factory/main.tf line 136, in resource "google_compute_shared_vpc_service_project" "shared_vpc_attachment":
136: resource "google_compute_shared_vpc_service_project" "shared_vpc_attachment" {

Error: Error retrieving IAM policy for compute subnetwork "projects/shared_vpc_host_name/regions/us-central1/subnetworks/10.128.0.0": googleapi: Error 403: Permission denied on resource project shared_vpc_host_name., forbidden
Run Code Online (Sandbox Code Playgroud)

google-api google-cloud-platform terraform devops terraform-provider-gcp

12
推荐指数
3
解决办法
4万
查看次数

aws_acm_certificate 似乎已经改变了它的状态输出,可能是由于提供者更新——我做错了吗?

Terraform v0.12.12
+ provider.aws v3.0.0
+ provider.template v2.1.2
Run Code Online (Sandbox Code Playgroud)

在我这样做之前:

resource "aws_route53_record" "derps" {
  name    = aws_acm_certificate.mycert[0].resource_record_name
  type    = aws_acm_certificate.mycert[0].resource_record_type
  zone_id = var.my_zone_id
  records = aws_acm_certificate.mycert[0].resource_record_value
  ttl     = 60
}
Run Code Online (Sandbox Code Playgroud)

大约一周前,这对我来说效果很好。

我刚刚做了一个计划,却出现了错误:

records = [aws_acm_certificate.mycert.domain_validation_options[0].resource_record_value]

This value does not have any indices.
Run Code Online (Sandbox Code Playgroud)

现在我不固定提供者版本,所以我假设我拉了一个更新的版本并且资源发生了变化。

在与这个斗争并意识到它不是一个列表(即使这样做show state时看起来确实像一个列表)我现在这样做是为了使它成为一个列表:

resource "aws_route53_record" "derps" {
  name    = sort(aws_acm_certificate.mycert.domain_validation_options[*].resource_record_name)[0]
  type    = sort(aws_acm_certificate.mycert.domain_validation_options[*].resource_record_type)[0]
  zone_id = var.my_zone_id
  records = [sort(aws_acm_certificate.mycert.domain_validation_options[*].resource_record_value)[0]]
  ttl     = 60
} 
Run Code Online (Sandbox Code Playgroud)

这导致没有变化,这是好的。但是,如果我使用他们现在使用 for_each 的文档中的示例来执行此操作:https : //registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/acm_certificate_validation

resource "aws_route53_record" "example" {
  for_each = {
    for …
Run Code Online (Sandbox Code Playgroud)

amazon-web-services amazon-route53 terraform

12
推荐指数
2
解决办法
3180
查看次数

Switch terraform 0.12.6 to 0.13.0 给了我 provider["registry.terraform.io/-/null"] 是必需的,但它已被删除

我在远程 terraform-cloud 中管理状态

我已经下载并安装了最新的 terraform 0.13 CLI

然后我删除了.terraform

然后我跑terraform init了,没有错误

然后我做了

? terraform apply -var-file env.auto.tfvars

Error: Provider configuration not present

To work with
module.kubernetes.module.eks-cluster.data.null_data_source.node_groups[0] its
original provider configuration at provider["registry.terraform.io/-/null"] is
required, but it has been removed. This occurs when a provider configuration
is removed while objects created by that provider still exist in the state.
Re-add the provider configuration to destroy
module.kubernetes.module.eks-cluster.data.null_data_source.node_groups[0],
after which you can remove the provider configuration again.

Releasing state lock. …
Run Code Online (Sandbox Code Playgroud)

terraform terraform-provider-aws amazon-eks

12
推荐指数
3
解决办法
7379
查看次数

Azure DevOps 管道中的条件阶段执行

我希望根据前一阶段中设置的变量的内容来执行 Azure DevOps 管道中的一个阶段。

这是我的管道:

stages:
  - stage: plan_dev
    jobs:
    - job: terraform_plan_dev
      steps:
      - bash: echo '##vso[task.setvariable variable=terraform_plan_exitcode;isOutput=true]2'
        name: terraform_plan

  - stage: apply_dev
    dependsOn: plan_dev
    condition: eq(stageDependencies.plan_dev.terraform_plan_dev.outputs['terraform_plan.terraform_plan_exitcode'], '2')
    jobs:
    - deployment: "apply_dev"
      ...
Run Code Online (Sandbox Code Playgroud)

apply_dev如果阶段plan_dev没有显示任何变化,我们的想法是跳过该阶段。背景是,我们在该阶段需要手动批准部署,plan_dev如果没有需要批准的更改,我们希望跳过该阶段。

不幸的是这似乎不起作用。无论变量是否terraform_plan_exitcode设置为期望值(2),都会apply_dev跳过该阶段。

对于语法,我遵循此处的文档

stageDependencies.StageName.JobName.outputs['StepName.VariableName']
Run Code Online (Sandbox Code Playgroud)

azure terraform azure-devops azure-pipelines

12
推荐指数
2
解决办法
2万
查看次数

对 Terraform 状态保密

我试图避免在 Terraform 状态下拥有秘密。

是否有更好的方法从 Secrets Manager 中的密钥设置 RDS 密码来执行此操作?

resource "null_resource" "master_password" {
  triggers = {
    db_host = module.myrdsdatabase.cluster_id
  }

  provisioner "local-exec" {
    command = <<TOF
    password=$(aws secretsmanager get-secret-value --secret-id myrdscreds | jq '.SecretString | fromjson | .password' | tr -d '"')
    aws rds modify-db-cluster --db-cluster-identifier ${module.myrdsdatabase.cluster_id} --master-user-password $password --apply-immediately
    TOF

    interpreter = ["bash", "-c"]
  }
}
Run Code Online (Sandbox Code Playgroud)

terraform

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

是否可以在将项目添加到 SQS 队列时触发 AWS Fargate 任务?

为了澄清起见,我想做的是当特定队列中有项目时触发 Fargate 任务。我已经使用本教程来了解我现在的情况。这工作正常,但我遇到的问题是每个文件上传(s3存储桶的结构是s3_bucket_name/{unknown_name}/known_file_names)都会导致任务被触发,我只希望/需要它每个{unknown_name}触发一次。此后,我更改了配置,以在检测到 test_file.txt 文件时将项目添加到队列中。是否可以在这样的队列上触发fargate任务?如果是这样,怎么办?

amazon-s3 amazon-sqs amazon-web-services amazon-ecs terraform

12
推荐指数
2
解决办法
3万
查看次数