远程管理Terraform的state

2,056次阅读
没有评论

共计 4628 个字符,预计需要花费 12 分钟才能阅读完成。

远程管理Terraform的state

用过terraform工具的小伙伴,是如何多人协作的呢?又是如何保存state呢?是保存在本地?还是保存在远程backend上?对于terraform的state,里面保存了我们IaC工程的状态,若是后续需要变更该工程的某个资源,就需要用到state来定位,否则直拉工程文件去apply会导致新建工程资源。有的人说data块中的filter也可以选取到指定资源,但是如果工程文件包含很多资源类型时就会略显繁琐无力,可谓没有技术含量,只有代码量。

使用oss保存state

terraform创建资源

此处用terraform创建以下资源:

  • IaC ram用户,一个只用来管理oss backend的ram用户
  • IaC ram用户组
  • IaC ram oss backend policy,一个只有指定oss bucket权限的策略
xadocker@xadocker-virtual-machine:~/workdir/terraform/oss_backend$ cat providers.tf 
terraform {
  required_providers {
    alicloud = {
      #source = "aliyun/alicloud"
      source = "local-registry/aliyun/alicloud"
      version = "1.166.0"
    }
  }
}
 
provider "alicloud" {
  access_key = "xxxxxxxdddddd"
  secret_key = "xxxxxxxdddddd"
  region = "cn-guangzhou"
}

xadocker@xadocker-virtual-machine:~/workdir/terraform/oss_backend$ cat terraform.tf
# 创建用户
resource "alicloud_ram_user" "user" {
  name         = "user_iac_xad"
  display_name = "iac_xad"
  mobile       = "86-15688888888"
  email        = "xadocker@xadocker.cn"
  comments     = "this is a user for iac: xadocker"
  force        = true
}

# 创建用户组
resource "alicloud_ram_group" "group" {
  name     = "group-tf"
  comments = "this is a group for tf"
  force    = true
}

# 将用户加入组
resource "alicloud_ram_group_membership" "membership" {
  group_name = alicloud_ram_group.group.name
  user_names = [alicloud_ram_user.user.name]
}

# 创建bucket
resource "alicloud_oss_bucket" "bucket" {
  bucket = "iac-tf-oss-backend"
  acl    = "private"
}

# 创建拥有指定oss bucket 的权限
resource "alicloud_ram_policy" "policy" {
  policy_name        = "iac-tf-oss-backend"
  policy_document    = <<EOF
    {
      "Statement": [
        {
          "Action": [
            "oss:*"
          ],
          "Effect": "Allow",
          "Resource": [
            "acs:oss:*:*:${alicloud_oss_bucket.bucket.bucket}",
            "acs:oss:*:*:${alicloud_oss_bucket.bucket.bucket}/*"
          ]
        }
      ],
        "Version": "1"
    }
  EOF
  description = "this is a policy for tf oss backend"
  force       = true
}

# 策略绑定到组上
resource "alicloud_ram_group_policy_attachment" "attach" {
  policy_name = alicloud_ram_policy.policy.name
  policy_type = alicloud_ram_policy.policy.type
  group_name  = alicloud_ram_group.group.name
}

# 获取该ram ak/sk并输出到文件中,ak/sk只输出一次,将文件删除后也不会再生成,只有重建该资源
resource "alicloud_ram_access_key" "ak" {
  user_name   = alicloud_ram_user.user.name
  secret_file = "aksk.txt"
}

创建资源

xadocker@xadocker-virtual-machine:~/workdir/terraform/oss_backend$ terraform init
xadocker@xadocker-virtual-machine:~/workdir/terraform/oss_backend$ terraform apply 

将state保存至oss

用上面资源创建好后,在terraform块中增加backend块,指定刚才创建的oss bucket,ak/sk也是用上面创建的,注意这里和我们原来provides块的ak/sk是可以不一样的

xadocker@xadocker-virtual-machine:~/workdir/terraform/oss_backend$ cat providers.tf 
terraform {
  backend "oss" {
    profile = "terraform"
    bucket  = "iac-tf-oss-backend"
    prefix  = "projectA/env_dev/"
    access_key = "xxxxxxx"
    secret_key = "xxxxxxx"
    region     = "cn-guangzhou"
  }

  required_providers {
    alicloud = {
      #source = "aliyun/alicloud"
      source = "local-registry/aliyun/alicloud"
      version = "1.166.0"
    }
  }
}
 
provider "alicloud" {
  access_key = "xxxxxxxdddddd"
  secret_key = "xxxxxxxdddddd"
  region = "cn-guangzhou"
}

修改后需要重新init该工程

xadocker@xadocker-virtual-machine:~/workdir/terraform/oss_backend$ 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 "local" backend to the
  newly configured "oss" backend. No existing state was found in the newly
  configured "oss" backend. Do you want to copy this state to the new "oss"
  backend? Enter "yes" to copy and "no" to start with an empty state.

  Enter a value: yes


Successfully configured the backend "oss"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...
- Reusing previous version of local-registry/aliyun/alicloud from the dependency lock file
- Using previously-installed local-registry/aliyun/alicloud v1.166.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

这时oss bucket中就会有个state文件terraform.tfstate,而我们本地的state文件则为空

xadocker@xadocker-virtual-machine:~/workdir/terraform/oss_backend$ ll
total 36
drwxrwxr-x 3 xadocker xadocker 4096 6月 19 16:45 ./
drwxrwxr-x 5 xadocker xadocker 4096 6月 19 10:47 ../
-rw-r--r-- 1 xadocker xadocker  160 6月 19 16:35 aksk.txt
-rw-rw-r-- 1 xadocker xadocker  558 6月 19 16:45 providers.tf
drwxr-xr-x 3 xadocker xadocker 4096 6月 19 16:45 .terraform/
-rw-r--r-- 1 xadocker xadocker  278 6月 19 16:34 .terraform.lock.hcl
-rw-rw-r-- 1 xadocker xadocker 1470 6月 19 16:44 terraform.tf
-rw-rw-r-- 1 xadocker xadocker    0 6月 19 16:45 terraform.tfstate
-rw-rw-r-- 1 xadocker xadocker 6758 6月 19 16:45 terraform.tfstate.backup

这时只需要有providers.tf、terraform.tf这两个文件就可在别的地方重用state了,如果需要把state保存到自建的oss服务器上,则在backend中使用endpoint

  backend "oss" {
    profile = "terraform"
    bucket  = "iac-tf-oss-backend"
    prefix  = "projectA/env_dev/"
    access_key = "xxxxxxx"
    secret_key = "xxxxxxx"
    region     = "cn-iac"
    endpoint   = "your-oss-endpoint.xadocker.com"
  }

使用consul保存state

创建服务器资源

安装consul

将state保存至consul

正文完
 1
xadocker
版权声明:本站原创文章,由 xadocker 2022-06-18发表,共计4628字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)