头图

春节前夕,一款名为《幻兽帕鲁(Palworld)》的游戏火爆出圈,在数天之内销量达到数百万,半月之内玩家达到了数千万之多。为了提升用户的体验,国内云厂商,诸如阿里云、华为云、腾讯云等纷纷推出幻兽帕鲁服务器,玩家可以在分钟级别内快速构建出开箱即用的幻兽帕鲁服务器。

对于快速构建云服务器这件事,很多时候,DevOps 人员可能是通过在控制台上,通过手动点击来快速创建。但是在云原生时代,有一个IaC(基础设施即代码)的技术,DevOps 人员无需手动操作,只需要通过自动化即可创建一些云资源。

比如在腾讯云上,一个云服务器是这样的参数:

如果用 IaC 的角度看,其实是这样的:

## instance info

resource "tencentcloud_instance" "cvm_almalinux" {
  instance_name = "jh-gitlab"
  availability_zone = "ap-ap-shanghai"
  image_id = "img-q95tlc25"
  instance_type = "S2.MEDIUM2"
  system_disk_type = "CLOUD_PREMIUM"
  system_disk_size  = 100
  hostname = "jh-gitlab"
  allocate_public_ip = true
  data_disks {
    data_disk_type = "CLOUD_PREMIUM"
    data_disk_size = 50
    encrypt        = false
  }
  security_groups = [
    "${tencentcloud_security_group.sg_bj.id}"
  ]

  vpc_id = "${tencentcloud_vpc.vpc_bj.id}"
  subnet_id = "${tencentcloud_subnet.subnet_bj_02.id}"
  internet_max_bandwidth_out = 10
  count = 1
}

## security group
resource "tencentcloud_security_group" "sg_bj" {
    name = "sg-jh-gitlab"    
}

resource "tencentcloud_security_group_rule" "sg_bj_1" {
    security_group_id = "${tencentcloud_security_group.sg_bj.id}"
    type = "ingress"
    cidr_ip = "0.0.0.0/0"
    ip_protocol = "tcp"
    port_range = "22,80,443"
    policy = "accept"
}

## vpc info
resource "tencentcloud_vpc" "vpc_bj" {
    name = "vpc_jh-gitlab"
    cidr_block = "10.0.0.0/16"
    is_multicast = false
}

## route table info
resource "tencentcloud_route_table" "rtb_vpc_bj" {
  vpc_id = tencentcloud_vpc.vpc_bj.id
  name   = "rtb-vpc-jh-gitlab"
}

## subnet info
resource "tencentcloud_subnet" "subnet_bj_01" {
    name = "jh-gitlab"
    cidr_block = "10.0.1.0/24"
    availability_zone = "ap-shanghai" 
    vpc_id = "${tencentcloud_vpc.vpc_bj.id}"
    route_table_id = "${tencentcloud_route_table.rtb_vpc_bj.id}"
}

这些信息都是以 .tf 的格式保存的。也就是 terrafrom 的格式保存的。

对于 terraform 来说,terraform 会将管理的云基础设施和配置的状态以文件的形式存储起来。terraform 会用这个状态和物理世界的实际资源做映射,并且对于这些资源的元数据进行追踪。一般来讲 state 文件是以 terrafrom.tfstate的形式保存到本地的。但是为了更好的保存该文件,并且做好版本控制、加密等,官方推荐可以将此文件保存到云端。

而极狐GitLab 就可以存储此文件。terrafrom 支持通过配置 backend(后端)来将 state 文件存储到对应的后端上。极狐GitLab 除了能够存储 terraform 文件外,还能实现以下功能:

  • 对于 Terraform state 文件进行版本控制
  • 对 state 文件进行加密
  • 对 state 进行锁定/解锁
  • 通过 gitlab ci 来远程执行 terraform plan和 terraform apply命令。

如果需要使用此功能,需要确保极狐GitLab 设置好了 terraform state 存储的配置。通过项目的设置 --> 通用 --> 可见性,项目功能,权限 --> 基础设施进行设置。

初始化 terraform state 并将极狐GitLab 作为 backend

要将极狐GitLab 配置为 terraform state 的 backend,需要在文件中做如下配置:

terraform {
  backend "http" {
  }
}

以腾讯云为例来讲,可以在 provider.tf 文件中写入如下配置:

provider "tencentcloud" {
  secret_id  = "你的腾讯云账号 secret id"
  secret_key = "你的腾讯云账号 secret key"
  region     = "ap-shanghai"
}

terraform {
  required_providers {
    tencentcloud = {
      source = "tencentcloudstack/tencentcloud"
      version = "1.81.70"
    }
  }
backend "http" {}
}

接下来只需要执行 terraform init即可。在初始化之前,需要先在极狐GitLab上创建一个存储 state 文件的项目。可在极狐GitLab 首页创建项目:

可以使用 Omnibus 来安装私有化部署的极狐GitLab 实例,安装详情可以查看极狐GitLab 安装官网

创建完毕,可以在项目 --> 运维中看到项目中存储的 terraform state 文件:

可以看到,新建的项目中并没有存储 terraform state 文件。可以根据界面上提示的 复制 Terraform init 命令来完成初始化,并且将 state 文件存储到此项目下。命令内容如下:

terraform init \
    -backend-config="address=https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME" \
    -backend-config="lock_address=https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME/lock" \
    -backend-config="unlock_address=https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME/lock" \
    -backend-config="username=majinghe" \
    -backend-config="password=$GITLAB_ACCESS_TOKEN" \
    -backend-config="lock_method=POST" \
    -backend-config="unlock_method=DELETE" \
    -backend-config="retry_wait_min=5"

这里面有两个环境变量 $TF_STATE_NAME和 $GITLAB_ACCESS_TOKEN。第一个是 terraform state 文件的名称,第二个是极狐GitLab 的 access token。将 terraform state 文件的名称设置为 jh-gitlab。

在极狐GitLab 首页上,点击头像 --> 编辑个人资料 --> 访问令牌创建个人访问令牌。

获取访问令牌的值,并将其以环境变量的形式导入:

export GITLAB_ACCESS_TOKEN="你的个人访问令牌"
export TF_STATE_NAME="jh-gitlab"

接着执行上述的 terrform init xxxx命令即可:

terraform init \
    -backend-config="address=https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME" \
    -backend-config="lock_address=https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME/lock" \
    -backend-config="unlock_address=https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME/lock" \
    -backend-config="username=majinghe" \
    -backend-config="password=$GITLAB_ACCESS_TOKEN" \
    -backend-config="lock_method=POST" \
    -backend-config="unlock_method=DELETE" \
    -backend-config="retry_wait_min=5"

Initializing the backend...

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

Initializing provider plugins...
- Finding tencentcloudstack/tencentcloud versions matching "1.81.70"...
- Installing tencentcloudstack/tencentcloud v1.81.70...
- Installed tencentcloudstack/tencentcloud v1.81.70 (verified checksum)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

╷
│ Warning: Incomplete lock file information for providers
│
│ Due to your customized provider installation methods, Terraform was forced to calculate lock file checksums locally
│ for the following providers:
│   - tencentcloudstack/tencentcloud
│
│ The current .terraform.lock.hcl file only includes checksums for linux_amd64, so Terraform running on another
│ platform will fail to install these providers.
│
│ To calculate additional checksums for another platform, run:
│   terraform providers lock -platform=linux_amd64
│ (where linux_amd64 is the platform to generate)
╵

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.

此时可以看到 terraform 初始化成功 Terraform has been successfully initialized!

接着执行 terraform plan:

terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with
the following symbols:
  + create

Terraform will perform the following actions:

  # tencentcloud_vpc.vpc_xiaoamge will be created
  + resource "tencentcloud_vpc" "vpc_xiaoamge" {
      + assistant_cidrs        = (known after apply)
      + cidr_block             = "10.0.0.0/16"
      + create_time            = (known after apply)
      + default_route_table_id = (known after apply)
      + dns_servers            = (known after apply)
      + docker_assistant_cidrs = (known after apply)
      + id                     = (known after apply)
      + is_default             = (known after apply)
      + is_multicast           = true
      + name                   = "vpc_xiaomage"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if
you run "terraform apply" now.

紧接着就可以在前面创建的项目下看到对应的 state 文件 jh-gitlab 了。

当然在 DevOps 最佳实践中,所有的 terraform 文件也可以存储在极狐GitLab 项目中,做好版本控制,terraform 命令的执行也可以和极狐GitLab CI/CD 集成起来。

将 terraform 相关的文件存储在极狐GitLab 的项目中,比如 provider.tf、variable.tf、cvm.tf 等。

然后在项目根目录下创建一个 .gitlab-ci.yml文件,内容如下:

variables:
  TF_DIR: ${CI_PROJECT_DIR}
  TF_STATE_NAME: "jh-gitlab"          
  ADDRESS: "https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME"

# Stages of the pipeline
stages:
  - validate
  - plan

# Image which will use in each stage
image:
  name: hashicorp/terraform:light
  entrypoint: [""]

# Script to be executed before each stage 
default:
  tags:
    - terraform
  before_script:
    - terraform --version
    - export GITLAB_ACCESS_TOKEN=$JH_ACCESS_TOKEN
    - cd ${TF_DIR} 
    - cp .terraformrc ~/
    - terraform init -reconfigure 
      -backend-config="address=https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME" 
      -backend-config="lock_address=https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME/lock" 
      -backend-config="unlock_address=https://jihulab.com/api/v4/projects/183534/terraform/state/$TF_STATE_NAME/lock" 
      -backend-config="username=majinghe" 
      -backend-config="password=$GITLAB_ACCESS_TOKEN" 
      -backend-config="lock_method=POST" 
      -backend-config="unlock_method=DELETE" 
      -backend-config="retry_wait_min=5"  

  
# To validate terraform files configuration
validate:
  stage: validate
  script:
    - terraform validate

# To check the plan of the infrastructure
plan:
  stage: plan
  script:
    - terraform plan 
  dependencies:              
    - validate

需要将 provider 需要的三个敏感信息:secret-id、 secret-key和极狐GitLab acess token 以环境变量的形式存储到极狐GitLab 上:

触发 CI/CD 流水线,可以看到流水线构建的结果:

其中,validate stage 的构建日志如下:

其中,plan stage 的构建日至如下:

其他的步骤诸如 apply、 destory也可以直接写在 CI/CD 流水线中,由于执行此步骤会直接创建对应的云资源或者删除对应的云资源,故不在此演示,但是原理是一样的。

使用 terraform 实现 IaC,通过操作代码就能实现云计算资源的创建和配置,整个过程能对变更做到版本控制,方便安全审计,而且用户无需直接操作云计算资源,权限管理也变得更加安全容易了。

使用上面的方法快速创建幻兽帕鲁游戏服务器,就会体验幻兽帕鲁游戏带来的酸爽体验了。


极狐GitLab
64 声望37 粉丝

极狐(GitLab) 以“核心开放”为原则,面向中国市场,提供开箱即用的开放式一体化安全DevOps平台——极狐GitLab。通过业界领先的优先级管理、安全、风险和合规性功能,实现产品、开发、QA、安全和运维团队间的高效协同...