【问题标题】:How can I use multible terraform tf files in one jenkins script?如何在一个 jenkins 脚本中使用多个 terraform tf 文件?
【发布时间】:2021-04-16 10:03:37
【问题描述】:

我正在尝试使用 jenkins 学习 terraform 的用法。我意识到我不能在同一个 github 存储库中使用 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文件有什么区别?他们看起来很相似?他们有相同的提供者。
  • 嗨;如果你仔细看,你会看到 ec2 和 s3 版本不同。
  • 他们有不同的名称标签。它们并不相似。

标签: amazon-web-services jenkins jenkins-pipeline terraform


【解决方案1】:

首先查看 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

【讨论】:

    【解决方案2】:

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

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

    Terraform 不在乎您使用 1 个或 100 个文件作为代码,但定义必须是唯一的。

    【讨论】:

      【解决方案3】:

      在查看您的 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"
      
      

      【讨论】:

        猜你喜欢
        • 2021-07-14
        • 1970-01-01
        • 2017-04-21
        • 1970-01-01
        • 2020-04-10
        • 2022-12-18
        • 1970-01-01
        • 2022-07-01
        • 1970-01-01
        相关资源
        最近更新 更多