【问题标题】:Terraform unable to use third party providersTerraform 无法使用第三方提供商
【发布时间】:2021-04-19 11:09:49
【问题描述】:

说明: 我正在尝试为 Terraform 使用 Elasticsearch 提供程序。由于没有来自 Elastic 或 Hashicorp 的官方版本,因此我尝试使用社区版本“https://registry.terraform.io/providers/phillbaker/elasticsearch/latest”。

Terraform 版本: Terraform v0.14.4

代码:

我尝试将所有内容放入 1 个 .tf 文件中。我还尝试为 Hashicorp 推荐的资源创建一个单独的模块。两种方法都会生成相同的错误消息。

terraform {
  required_providers {
    elk = {
      source  = "phillbaker/elasticsearch"
      version = "1.5.1"
    }
  }
}

provider "elk" {
  url = "https://<my_elk_server>"
}

resource "elasticsearch_index" "index" {
  name = var.elasticsearch_index_name
}

问题:

terraform init 由于某种原因无法在 Terraform 注册表中找到合适的提供程序。

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/elasticsearch...
- Finding phillbaker/elasticsearch versions matching "1.5.1"...
- Installing phillbaker/elasticsearch v1.5.1...
- Installed phillbaker/elasticsearch v1.5.1 (self-signed, key ID 02AD42CD82B6A957)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:

Error: Failed to query available provider packages
https://www.terraform.io/docs/plugins/signing.html

Could not retrieve the list of available versions for provider
hashicorp/elasticsearch: provider registry registry.terraform.io does not have
a provider named registry.terraform.io/hashicorp/elasticsearch

If you have just upgraded directly from Terraform v0.12 to Terraform v0.14
then please upgrade to Terraform v0.13 first and follow the upgrade guide for
that release, which might help you address this problem.

没有生成 tfstate 文件。

如何使用 Terraform Registry 中的第三方提供程序?

【问题讨论】:

    标签: terraform hashicorp


    【解决方案1】:

    在您的 required_providers 块中,您告诉 Terraform 您打算在此模块中将此提供程序称为“elk”:

        elk = {
          source  = "phillbaker/elasticsearch"
          version = "1.5.1"
        }
    

    通常您会将提供者的本地名称设置为与提供者源地址的“类型”部分相同,如下所示:

        elasticsearch = {
          source  = "phillbaker/elasticsearch"
          version = "1.5.1"
        }
    

    如果您以这种方式更改本地名称,那么在模块中的其他地方使用对 elasticsearch 的引用应该按照您的意图引用社区提供者。

    请注意,这意味着您还需要更改 provider 块,使其具有匹配的本地名称:

    provider "elasticsearch" {
      url = "https://<my_elk_server>"
    }
    

    这里的另一种方法是继续使用elk 作为名称,然后更改其余配置以正确引用该非默认名称。我不推荐这样做,因为通常我希望本地名称仅在您的模块依赖于具有相同类型名称的两个提供程序的不寻常情况下与类型不匹配,但我提到这一点是希望它有助于理解 Terraform 语言在未明确给出时如何推断提供者依赖关系:

    terraform {
      required_providers {
        elk = {
          source  = "phillbaker/elasticsearch"
          version = "1.5.1"
        }
      }
    }
    
    # "elk" here is matched with the local names in the
    # required_providers block, so this will work.
    provider "elk" {
      url = "https://<my_elk_server>"
    }
    
    # This "elasticsearch_" prefix causes Terraform to look
    # for a provider with the local name "elasticsearch"
    # by default...
    resource "elasticsearch_index" "index" {
      # ...so if you've given the provider a different local
      # name then you need to associate the resource with
      # the provider configuration explicitly:
      provider = elk
    
      name = var.elasticsearch_index_name
    }
    

    我希望大多数 Terraform 用户会发现上述方法令人惊讶,因此为了使用熟悉的 Terraform 习语,我建议改为遵循我的第一个建议,将本地名称重命名为 elasticsearch,这将允许自动资源-to-provider 关联工作。

    【讨论】:

    • 谢谢你的回答马丁。我设法通过使用您建议的第一种方法使其工作: terraform { required_providers { elasticsearch = { source = "phillbaker/elasticsearch" version = "1.5.1" } } } provider "elasticsearch" { url = "127.0.0.1:9200 " }
    • 但是,如果我尝试将资源移动到单独的模块:module "elastic" { index_name = var.index_name index_pattern = var.index_pattern source = "../../modules/elastic"我再次得到同样的错误。即使我为模块中的每个资源指定 provider = elasticsearch,也找不到提供程序。
    【解决方案2】:

    所以,经过测试,似乎将整个代码放在同一个 .tf 文件中就可以了。

    terraform {
      required_providers {
        elasticsearch = {
          source  = "phillbaker/elasticsearch"
          version = "1.5.1"
        }
      }
    }
    
    provider "elasticsearch" {
      url = "http://127.0.0.1:9200"
    }
    
    resource "elasticsearch_index" "index" {
      name     = var.index_name
    }
    

    如果你想为它创建一个单独的模块,你可以从另一个模块中获取它:

    module "elastic" {
      index_name    = var.index_name
    
      source        = "./modules/elastic"
    }
    

    查看 Martin 的答案以获取更多信息。

    【讨论】:

      猜你喜欢
      • 2023-01-22
      • 1970-01-01
      • 2021-11-01
      • 2021-09-29
      • 1970-01-01
      • 2014-09-11
      • 2021-07-30
      • 1970-01-01
      • 2017-05-04
      相关资源
      最近更新 更多