如何在一个 jenkins 脚本中使用多个 terraform tf 文件?

How can I use multible terraform tf files in one jenkins script?

我正在尝试学习 jenkins 的 terraform 用法。我意识到我不能在同一个 github repository.I 中使用 2 个 tf 文件有 2 个 tf 文件:Providers.tf 和 Provider2.tf

Provider.tf:

#OpenShot Terraform Project
provider "aws" {
  region  = "eu-west-2"
}

resource "aws_s3_bucket" "b" {
  bucket = "my-tf-test-bucket-leanscale-2"
  acl    = "private"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {a
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}


resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t2.micro"

  tags = {
    Name = "HelloWorld-leanscale-2"
  }
}

Provider2.tf:

#OpenShot Terraform Project
provider "aws" {
  region  = "eu-west-2"
}

resource "aws_s3_bucket" "b2" {
  bucket = "my-tf-test-bucket-leanscale-3"
  acl    = "private"

  tags = {
    Name        = "My bucket2"
    Environment = "Dev"
  }
}

data "aws_ami" "ubuntu2" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}


resource "aws_instance" "web2" {
  ami           = data.aws_ami.ubuntu2.id
  instance_type = "t2.micro"

  tags = {
    Name = "HelloWorld-leanscale-3"
  }
}

詹金斯脚本:

pipeline {
    agent any
    tools {
        
        terraform 'terraform-leanscale'
    }
    
      environment {
    TF_WORKSPACE = 'default' //Sets the Terraform Workspace
    TF_IN_AUTOMATION = 'true'
    AWS_ACCESS_KEY_ID = "${params.AWS_ACCESS_KEY_ID}"
    AWS_SECRET_ACCESS_KEY = "${params.AWS_SECRET_ACCESS_KEY}"
    }

    stages {
        stage('Git Checkout') {
            steps {
               git branch: 'staging', credentialsId: 'leanscale', url: 'https://github.com/yusufkaratoprak/leanscale_yusuf.git'
            }
        }
        
        stage('terraform-init') {
            steps {
                sh label: '', script: 'terraform init' 
            }
        }
        
        stage('terraform-apply') {
            steps {
                sh label: '', script: 'terraform apply --auto-approve' 
            }
        }
        
    }
}



```C
[Pipeline] sh
+ terraform init
[31mThere are some problems with the configuration, described below.

The Terraform configuration must be valid before initialization so that
Terraform can determine which modules and providers need to be installed.[0m[0m
[31m
[1m[31mError: [0m[0m[1mArgument or block definition required[0m

[0m  on provider.tf line 24, in data "aws_ami" "ubuntu":
  24:   filter {[4ma[0m
[0m
An argument or block definition is required here. To set an argument, use the
equals sign "=" to introduce the argument value.
[0m[0m
[31m
[1m[31mError: [0m[0m[1mDuplicate provider configuration[0m

[0m  on provider2.tf line 2:
   2: [4mprovider "aws"[0m {
[0m
A default (non-aliased) provider configuration for "aws" was already given at
provider.tf:2,1-15. If multiple configurations are required, set the "alias"
argument for alternative configurations.
[0m[0m
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (terraform-apply)
Stage "terraform-apply" skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 1
Finished: FAILURE

How can OI use multiple tf files in the same repository by Jenkins script?

首先查看该 TF 代码,它可能全部 运行 在同一个文件中,只有一个提供程序块,因为没有什么要求它在两个单独的文件中。

如果您想要资源的逻辑分离,您可以将提供程序块(在两个文件中相同)移动到另一个文件,可能称为 provider.tf 然后有 resources1.tfresources2.tf(或者 Terraform 不关心的任何东西,只要它具有 .tf 扩展名即可。

但是,如果您出于某种原因希望它位于两个文件中,具有两个提供程序,Terraform 允许提供程序的别名,这样您就可以拥有多个相同的提供程序 见 https://www.terraform.io/docs/language/providers/configuration.html#alias-multiple-provider-configurations

或者如果您根本不想更改代码文件

在您的管道中,您可以重命名 provider2,运行 provider1 的阶段。清理 .terraform 文件夹,重命名 provider1 并将 provider2 设置回其正确名称和 运行 该文件的阶段。

将它们放在 Git 仓库中的不同目录中

然后您可以使用 dir 命令切换到每个目录和 运行 Terraform

dir("provider1"){
   sh "terraform init"
   sh "terraform apply"

TBH 正确答案是第一个.....将提供者移到它自己的文件中。

编辑: 由于行

上的额外 a,您还会收到 providers.tf 第 24 行的错误
filter {a

将此声明移到它自己的文件中而不是复制

provider "aws" {
  region  = "eu-west-2"
}

Terraform 不关心代码使用一个文件还是 100 个文件,但定义必须是唯一的。

查看您的 Terraform 代码提供程序对于这两个文件是相同的。所以通过创建 provider.tf 和只写

来避免冗余
provider "aws" {
  region  = "eu-west-2"
}

next 不要在单独的两个文件中编写代码,而是使用模块结构。 通过给一些 awsinstance.tf


    enter code here
    resource "aws_s3_bucket" "b2" {
      bucket = "my-tf-test-bucket-leanscale-3"
      acl    = "private"

  tags = {
    Name        = "My bucket2"
    Environment = "Dev"
  }
}

data "aws_ami" "ubuntu2" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}


resource "aws_instance" "web2" {
  ami           = data.aws_ami.ubuntu2.id
  instance_type = "t2.micro"

  tags = {
    Name = "HelloWorld-leanscale-3"
  }
}

,而不是直接在该目录中使用 variable.tf 传递值。 喜欢

    resource "aws_s3_bucket" "b2" {
      bucket = var.bucketname
      acl    = var.acl

}

并在变量文件中

variable "bucketname"{
}

提及所有变量 然后在 main.tf 中使用模块“任何名称”并提供上述文件的来源并传递所需的参数。并在这里也提到 variable.tf 并使用

传递值
variable.tfvars

variable bucketname = ""my-tf-test-bucket-leanscale-3"