Terraform Provider:多云资源管理
Terraform Provider:多云资源管理
什么是Terraform Provider
Provider是Terraform与云平台、SaaS服务或其他API交互的插件。每个Provider负责理解和操作特定资源类型的CRUD操作。Terraform Registry提供了数千个Provider。
Provider配置
AWS Provider
# providers.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# 默认配置
provider "aws" {
region = "us-west-2"
}
# 多区域配置
provider "aws" {
alias = "us_east"
region = "us-east-1"
}
provider "aws" {
alias = "eu_west"
region = "eu-west-1"
}
# 使用别名的资源
resource "aws_s3_bucket" "us" {
provider = aws.us_east
bucket = "my-us-bucket"
}
resource "aws_s3_bucket" "eu" {
provider = aws.eu_west
bucket = "my-eu-bucket"
}
Azure Provider
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}
provider "azurerm" {
features {}
# 使用Service Principal认证
client_id = var.client_id
client_secret = var.client_secret
tenant_id = var.tenant_id
subscription_id = var.subscription_id
}
# 或使用环境变量
# export ARM_CLIENT_ID="xxx"
# export ARM_CLIENT_SECRET="xxx"
# export ARM_TENANT_ID="xxx"
# export ARM_SUBSCRIPTION_ID="xxx"
Google Cloud Provider
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
provider "google" {
project = "my-project-id"
region = "us-central1"
}
# 多项目配置
provider "google" {
alias = "project_b"
project = "project-b-id"
region = "europe-west1"
}
resource "google_compute_instance" "project_a" {
name = "instance-a"
machine_type = "n2-standard-2"
zone = "us-central1-a"
}
resource "google_compute_instance" "project_b" {
provider = google.project_b
name = "instance-b"
machine_type = "n2-standard-2"
zone = "europe-west1-b"
}
Kubernetes Provider
terraform {
required_providers {
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.23"
}
helm = {
source = "hashicorp/helm"
version = "~> 2.11"
}
}
}
provider "kubernetes" {
config_path = "~/.kube/config"
config_context = "my-cluster"
}
provider "helm" {
kubernetes {
config_path = "~/.kube/config"
}
}
# 使用Kubernetes Provider创建资源
resource "kubernetes_namespace" "app" {
metadata {
name = "my-app"
}
}
resource "kubernetes_deployment" "app" {
metadata {
name = "my-app"
namespace = kubernetes_namespace.app.metadata[0].name
}
spec {
replicas = 3
selector {
match_labels = {
app = "my-app"
}
}
template {
metadata {
labels = {
app = "my-app"
}
}
spec {
container {
name = "my-app"
image = "nginx:latest"
port {
container_port = 80
}
}
}
}
}
}
多云配置
统一多云架构
# multi-cloud.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
}
}
# AWS基础设施
module "aws_infra" {
source = "./modules/aws"
providers = {
aws = aws.us_east
}
vpc_cidr = "10.0.0.0/16"
}
# Azure基础设施
module "azure_infra" {
source = "./modules/azure"
resource_group = "my-rg"
location = "East US"
}
# GCP基础设施
module "gcp_infra" {
source = "./modules/gcp"
providers = {
google = google
}
project_id = "my-project"
}
跨云资源引用
# 使用外部数据源获取跨云信息
data "external" "aws_ip" {
program = ["aws", "ec2", "describe-instances", "--query", "Reservations[0].Instances[0].PublicIpAddress", "--output", "text"]
}
# 创建跨云DNS记录
resource "aws_route53_record" "app" {
zone_id = "Z1234567890"
name = "app.example.com"
type = "A"
ttl = 300
records = [data.external.aws_ip.result.stdout]
}
Provider版本管理
版本锁定
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "= 5.0.0" # 精确版本
}
azure = {
source = "hashicorp/azurerm"
version = "~> 3.0" # 兼容3.x
}
google = {
source = "hashicorp/google"
version = ">= 4.0, < 6.0" # 版本范围
}
}
}
版本升级
# 查看可用版本
terraform providers
# 升级Provider
terraform init -upgrade
# 查看版本约束
terraform version
自定义Provider
使用Terraform Plugin SDK
package main
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
)
func Provider() *schema.Provider {
return &schema.Provider{
Schema: map[string]*schema.Schema{
"api_key": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("MY_API_KEY", nil),
Description: "API密钥",
Sensitive: true,
},
"endpoint": {
Type: schema.TypeString,
Optional: true,
Default: "https://api.example.com",
Description: "API端点",
},
},
ResourcesMap: map[string]*schema.Resource{
"myresource_instance": resourceMyResource(),
},
ConfigureFunc: providerConfigure,
}
}
func main() {
plugin.Serve(&plugin.ServeOpts{
ProviderFunc: Provider,
})
}
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
apiKey := d.Get("api_key").(string)
endpoint := d.Get("endpoint").(string)
client, err := NewClient(apiKey, endpoint)
if err != nil {
return nil, err
}
return client, nil
}
Provider调试
日志配置
# 启用调试日志
export TF_LOG=TRACE
export TF_LOG_PATH=./terraform.log
# 特定Provider日志
export TF_LOG=TRACE
export TF_LOG_PROVIDER=TRACE
# 运行Terraform
terraform plan
Provider缓存
# 清除Provider缓存
rm -rf .terraform/
# 手动下载Provider
terraform init -plugin-dir=./plugins
# 使用镜像缓存
terraform init \
-filesystem-mirror=/path/to/mirror \
-network-mirror=https://mirror.example.com
常见问题
# Provider版本冲突
# 查看依赖图
terraform providers graph | dot -Tpng > providers.png
# 认证失败
# 检查环境变量
env | grep -E "(AWS_|ARM_|GOOGLE_)"
# Provider下载失败
# 配置网络代理
export HTTP_PROXY=http://proxy:8080
export HTTPS_PROXY=http://proxy:8080
terraform init
最佳实践
- 版本锁定:在生产环境中锁定Provider版本
- 多区域/多账户:使用Provider别名区分
- 认证管理:使用环境变量或密钥管理服务
- 缓存配置:配置Provider镜像加速下载
- 定期更新:定期升级Provider获取新功能和修复