更新时间:2022-02-10 GMT+08:00

Backend

默认情况下,通过Terraform完成资源的创建和修改后,会将资源的状态和属性信息会保存在当前目录下的 terraform.tfstate 文件中。这个 state 文件可以看作是Terraform存储资源属性的映射,当执行 "terraform show" 命令时,Terraform直接读取这个 state 文件,无需再去调用云平台的API查询。

Terraform后续的 'plan' 和 'apply' 操作,都是基于当前的模块配置和 state 文件进行比较。如果 state 文件被损坏或者被删除,Terraform会认为其管理的资源也发生了变更和移除。此时再执行 'apply' 命令将会按照模块的定义变更或者重建资源,直到模块对资源的定义与 state 中的映射保持一致。如果实际的资源依然存在于云平台中,这将会导致资源的重复创建或者创建失败。

在团队协作中,如果想维护同一套资源,需要将资源的配置文件和 state 文件一起拷贝,这无形中增加了代码维护的成本。为了解决这个问题,Terraform提供了远端存储的能力 ,即将 state 文件存放在远端的一个服务中,并支持锁定,实现代码与 state 的管理分离,提升了管理的灵活性。

Backend 是实现远端存储的机制。通过在 terraform块中声明 backend嵌套块,并指定不同的Backend 类型标签,可以将 state 文件存储在不同的远端服务中,如AWS S3,HashiCorp Consul,etcd等。

在华为云中使用S3 Backend

由于华为云的OBS (对象存储服务) 兼容AWS S3接口,且S3 Backend支持自定义endpoint,我们可以利用S3 Backend将 state 文件存储在华为云OBS桶中操作步骤如下:

  1. 在terraform块中配置backend

    terraform {
      backend "s3" {
        bucket   = "backendbucket"
        key      = "myproject/terraform.tfstate"
        region   = "cn-north-1"
        endpoint = "obs.cn-north-1.myhuaweicloud.com"
    
        skip_region_validation      = true
        skip_metadata_api_check     = true
        skip_credentials_validation = true
      }
    }

    参数说明:

    • bucket:桶名称
    • key:对象名称;
    • region:OBS桶所属地区;
    • endpoint:OBS为每个区域提供的终端节点,各区域的终端节点详情参照华为云地区和终端节点
    • skip*:调用AWS S3 API时跳过部分参数的校验和检查;

  2. 定义AK/SK环境变量

    OBS服务通过AK/SK对请求进行认证,用户可以在IAM服务中获取AK和SK,获取方法请参见华为AK/SK获取访问密钥。然后将AK/SK导出为环境变量:

    $ export AWS_ACCESS_KEY_ID="******"
    $ export AWS_SECRET_ACCESS_KEY="******"

  3. 执行 terraform init 命令

    配置完Backend后,需要执行terraform init命令对Backend进行初始化,首次执行时会有以下提示:

    $ terraform init
    
    Initializing the backend...
    Backend configuration changed!
    
    Terraform has detected that the configuration specified for the backend
    has changed. Terraform will now check for existing state in the backends.
    
    Successfully configured the backend "s3"! Terraform will automatically
    use this backend unless the backend configuration changes.
    
    Initializing provider plugins...
    ......
    Terraform has been successfully initialized!

    如果初始化失败,则会有以下提示:

    Error:No valid credential sources found for AWS Provider.
    Please see https://terraform.io/docs/providers/aws/index.html for more information on
    providing credentials for the AWS Provider

    此时应检查Backend的配置参数和环境变量是否正确。如果当前目录下已经存在"terraform.tfstate"文件,则会提示是否将这个"state"文件同步至远端。

    $ terraform init
    
    Initializing the backend...
    Do you want to copy existing state to the new backend?
      Pre-existing state was found while migrating the previous "s3" backend to the
      newly configured "s3" backend. No existing state was found in the newly
      configured "s3" backend. Do you want to copy this state to the new "s3"
      backend? Enter "yes" to copy and "no" to start with an empty state.
    
      Enter a value:

    输入"yes"后继续执行远程同步。