一、什么是Terraform
Terraform是一种开源工具,用于安全高效地预览,配置和管理云基础架构和资源。Terraform的命令行接口(CLI)提供一种简单机制,用于将配置文件部署到阿里云或其他任意支持的云上,并对其进行版本控制。
Terraform的主要优势如下:
- 多云部署
Terraform适用于多云方案,将类似的基础结构部署到阿里云、其他云提供商或者本地数据中心。开发人员能够使用相同的工具和相似的配置文件同时管理不同云提供商的资源。
- 自动化管理
Terraform能够创建配置文件的模板,以可重复、可预测的方式定义、预配和配置ECS资源,减少因人为因素导致的部署和管理错误。能够多次部署同一模板,创建相同的开发、测试和生产环境。
- 基础架构即代码(Infrastructure as Code)
可以用代码来管理维护资源。允许保存基础设施状态,从而使您能够跟踪对系统(基础设施即代码)中不同组件所做的更改,并与其他人共享这些配置
- 降低开发成本
通过按需创建开发和部署环境来降低成本。并且,您可以在系统更改之前进行评估。
二、安装Terraform
三、安装阿里云Terraform Provider
阿里云作为国内第一家与 Terraform 集成的云厂商,terraform-provider-alicloud目前已经提供了超过 163 个 Resource 和 113 个 Data Source,覆盖计算,存储,网络,负载均衡,CDN,容器服务,中间件,访问控制,数据库等超过35款产品,已经满足了大量大客户的自动化上云需求。
在安装完Terraform之后,有两种方式去安装阿里云的Terraform Provider:在线安装和本地编译安装。
3.1 在线安装
每个Terraform的Provider都有一个全网标识符,该标识符由三部分组成,分别为hostname,namespace和type,即//。hostname是指分发、下载Provider的域名,默认为registry.terraform.io。namspaces是指提供、开发Provider的组织的命名空间,默认为hashicorp。type是指Provider的具体类型,例如阿里云的Provider的type为alicloud。
基于每个Provider的全网标识符,Terraform会自动下载和安装对应的Provider到本地。以阿里云的Provider为例,在线安装的步骤如下:
- 创建一个terraform工作目录(文件夹),并在该目录下创建一个名为terraform.tf的文件。
该文件用于维护后续所有terraform相关的配置。
- 在terraform.tf文件中配置如下内容
terraform { required_providers { alicloud = { source = "hashicorp/alicloud" version = "1.164.0" } } }
- 在terraform工作目录下执行terraform init命令
上述命令会默认去registry.terraform.io的hashicorp命名空间里下载Provideralicloud的1.164.0版本,并安装到本地。执行完毕后,如果提示Terraform has been successfully initialized!表示安装成功。
3.2 本地编译安装
本地编译安装的原理是用户自行下载阿里云Provider的源码,在本地编译后,将编译好的Provider放到指定目录下,以此方式完成安装。其主要步骤如下。
1. 下载阿里云Provider源码
源码地址:https://github.com/aliyun/terraform-provider-alicloud
在上述地址下载源码的ZIP包到本地并解压;或者执行下面的命令下载
git clone git@github.com:aliyun/terraform-provider-alicloud.git
2. 编译Provider
进入Provider源码目录(terraform-provider-alicloud/),执行编译命令
make build
编译完成后,进入编译生成的bin/目录,执行以下命令,解压生成的编译包。
tar -zxvf terraform-provider-alicloud_darwin-amd64.tgz
注:编译一共生成3个编译包:xxx_darwin-amd64.tgz、xxx_linux-amd64.tgz和xxx_windows-amd64.tgz,分别对应于Mac OS、Linux和Windows操作系统,根据自己的操作系统选择对应的编译包解压即可。
解压完成后,进入解压出的bin/目录下即可看到编译生成的二进制文件terraform-provider-alicloud。
3. 创建本地Provider目录
选择一个本地的目录(如/Users/licheng/terraform_lib/),在该目录下创建如下目录层级
/Users/licheng/terraform_lib/providers/registry.terraform.io/hashicorp/alicloud/1.164.0/darwin_amd64
上述目录的层级结构如下
base directory(e.g. /Users/licheng/terraform_lib/providers/) └── <hostname>(e.g. registry.terraform.io) └── <namespace>(e.g. hashicorp) └── <type>(e.g. alicloud) └── <version>(e.g. 1.164.0) └── <your OS>(e.g. darwin_amd64)
其中和需要依据自己安装的阿里云Provider版本以及当前操作系统做修改。
4. 拷贝编译好的Provider
将第2步中编译好的二进制文件拷贝到第3步创建的目录之中
cp terraform-provider-alicloud xxx/providers/registry.terraform.io/hashicorp/alicloud/1.164.0/darwin_amd64
5. 安装Provider
安装步骤如下:
1)创建一个terraform工作目录(文件夹),并在该目录下创建一个名为terraform.tf的文件。该文件用于维护后续所有terraform相关的配置。
2)在terraform.tf文件中配置如下内容
terraform { required_providers { alicloud = { source = "hashicorp/alicloud" version = "1.164.0" } } backend "local" {} }
3)在$HOME目录下创建.terraformrc文件
touch ~/.terraformrc
配置.terraformrc文件内容如下
provider_installation { filesystem_mirror { path = "/Users/licheng/terraform_lib/providers" include = ["registry.terraform.io/*/*"] } }
其中path的值填写上述步骤3中创建的目录(到providers这一级即可)
4)在terraform的工作目录下执行terraform init命令
执行完毕后,如果提示Terraform has been successfully initialized!表示安装成功。
注:不同于在线安装的方式,上述命令不再会去线上下载,而是会默认去/Users/licheng/terraform_lib/providers(.terraformrc中配置的path目录)下寻找Provideralicloud的1.164.0版本,并进行安装。
四、使用Terraform管理SLS
4.1 创建Project
如果想要使用terraform创建一个SLS Project:
- 在terraform.tf文件中增加如下配置内容
provider "alicloud" { access_key = "xxxxxx" secret_key = "xxxxxx" region = "cn-hangzhou" } resource "alicloud_log_project" "test-project-1" { name = "test-project-1" description = "create by terraform" }
- 在terraform工作目录下执行terraform apply命令
输入yes确认执行后,如果提示Apply complete! Resources: 1 added, 0 changed, 0 destroyed.表示Project创建成功
4.2 创建Logstore
如果想要在上一步创建出的Project内,创建2个Logstore:
- 在terraform.tf文件中增加如下配置内容
resource "alicloud_log_store" "test-logstore-1" { project = alicloud_log_project.test-project-1.name name = "test-logstore-1" retention_period = 365 shard_count = 2 auto_split = true max_split_shard_count = 64 append_meta = true } resource "alicloud_log_store" "test-logstore-2" { project = alicloud_log_project.test-project-1.name name = "test-logstore-2" retention_period = 180 shard_count = 4 auto_split = true max_split_shard_count = 64 append_meta = true }
- 在terraform工作目录下执行terraform apply命令
输入yes确认执行后,如果提示Apply complete! Resources: 2 added, 0 changed, 0 destroyed.表示两个Logstore成功在4.1步骤中的Project下创建出来。
4.3 删除Project&Logstore
如果想要删除某个Project或者Logsotre,只需要把terraform.tf中对应的配置删除,然后重新执行terraform apply命令即可。例如,需要删除步骤4.2中创建出的test-logsotre-2:
- 在terraform.tf中删除resource "alicloud_log_store" "test-logstore-2的相关配置
- 执行terraform apply命令,如果提示Apply complete! Resources: 0 added, 0 changed, 1 destroyed.表示删除成功。
4.4 更多SLS资源的相关操作
参考阿里云Provider官方文档中Log Service (SLS)相关的部分
五、使用Terraform玩转SLS数据加工
5.1 创建数据加工任务
5.1.1 创建一个基本的数据加工任务
接着上述第4节中的操作,我们已经利用Terraform创建出了一个Projecttest-project-1,该Project包含两个Logstoretest-logstore-1和test-logstore-2。现在我们想要在test-logstore-1上创建一个数据加工任务,把该Logstore的数据加工处理后,传输到test-logstore-2之中。
对于上述需求,我们继续在Terrform的配置文件terraform.tf中增加以下配置内容
resource "alicloud_log_etl" "test-etl-job-1" { etl_name = "etl_name_1" display_name = "测试数据加工任务" description = "created by terraform" project = alicloud_log_project.test-project-1.name logstore = alicloud_log_store.test-logstore-1.name access_key_id = "xxxxxx" access_key_secret = "xxxxxx" script = "e_set('source', 'terraform')" etl_sinks { name = "target_name1" project = alicloud_log_project.test-project-licheng-1.name logstore = alicloud_log_store.test-logstore-2.name endpoint = "cn-hangzhou.log.aliyuncs.com" access_key_id = "xxxxxx" access_key_secret = "xxxxxx" } }
上述配置将以test-logstore-1作为源Logstore,test-logstore-2作为目标Logstore,创建一个加工逻辑为e_set('source', 'terraform')的加工任务。该加工任务默认的加工时间范围是所有时间
,即从源Logstore的第一条日志开始,持续进行日志加工。
5.1.2 设置不同的鉴权方式
上述5.1.1中设置了使用密钥对(AK/SK)的方式进行鉴权,如果不想要使用此方式,也可以使用RAM角色的鉴权方式(数据加工默认角色或者自定义角色)。以数据加工默认角色为例,在完成RAM角色的创建和授权后,只需要把上述配置中的access_key_id和access_key_secret参数替换为role_arn即可。
resource "alicloud_log_etl" "test-etl-job-1" { ... role_arn = "acs:ram::xxxxxx:role/aliyunlogetlrole" ... etl_sinks { name = "target_name1" project = alicloud_log_project.test-project-licheng-1.name logstore = alicloud_log_store.test-logstore-2.name role_arn = "acs:ram::xxxxxx:role/aliyunlogetlrole" }
除此之外,还可以使用KMS加密后的AK/SK密钥对来进行鉴权,来提高AK/SK的安全性,防止泄露。具体用法参考kms_encrypted_access_key。
5.1.3 设置多个输出目标
如果想要为加工任务配置多个输出目标,在配置中添加多个etl_sinks字段即可
resource "alicloud_log_etl" "test-etl-job-1" { etl_name = "etl_name_1" ... etl_sinks { name = "target_name1" project = alicloud_log_project.test-project-licheng-1.name logstore = alicloud_log_store.test-logstore-2.name ... } etl_sinks { name = "target_name2" project = alicloud_log_project.test-project-licheng-1.name logstore = alicloud_log_store.test-logstore-3.name ... } }
5.1.4 设置加工时间范围
上述5.1.1中的基本配置中,没有配置加工的时间范围,因此默认加工所有时间的日志,即从源Logstore的第一条日志开始,持续进行日志加工。如果想要自定义加工时间范围,使用from_time和to_time两个参数即可
resource "alicloud_log_etl" "test-etl-job-1" { etl_name = "etl_name_1" display_name = "测试数据加工任务" ... from_time = 1650630000 to_time = 1650630600 script = "e_set('source', 'terraform')" etl_sinks { name = "target_name1" ... } }
其中from_time和to_time两个参数的格式均为时间戳(整数类型),分别表示加工任务处理的起始时间和结束时间。这两个参数均为可选参数,如果from_time不填的话,默认值为0,表示从第一条日志开始加工;如果to_time不填的话,默认值为0,表示会持续加工新来的日志。
5.2 管理数据加工任务
5.2.1 停止数据加工任务
如果想要停止一个正在运行中的数据加工任务,只需在Terraform配置中增加一个字段status,并将值设置为STOPPED即可。修改加工任务的Terrform配置如下:
resource "alicloud_log_etl" "test-etl-job-1" { status = "STOPPED" etl_name = "etl_name_1" display_name = "测试数据加工任务" ... etl_sinks { name = "target_name1" ... } }
然后执行terraform apply命令,如果提示Apply complete! Resources: 0 added, 1 changed, 0 destroyed.表示停止任务成功。
5.2.2 启动数据加工任务
如果想要重启一个已经停止的数据加工任务,只需要修改字段status的值为RUNNING即可
resource "alicloud_log_etl" "test-etl-job-1" { status = "RUNNING" etl_name = "etl_name_1" display_name = "测试数据加工任务" ... etl_sinks { name = "target_name1" ... } }
修改配置文件后,执行terraform apply命令,如果提示Apply complete! Resources: 0 added, 1 changed, 0 destroyed.表示重启任务成功。
5.2.3 删除数据加工任务
如果想要删除数据加工任务,只需要把terraform.tf中对应的配置删除,然后重新执行terraform apply命令即可。例如,需要删除上述步骤中创建出的测试数据加工任务:
- 在terraform.tf中删除resource "alicloud_log_etl" "test-etl-job-1的相关配置
- 执行terraform apply命令,如果提示Apply complete! Resources: 0 added, 0 changed, 1 destroyed.表示删除成功。
5.3 导入数据加工任务
上述步骤中所有的资源都是由Terraform创建出来的,如果线上的加工任务不是由Terraform创建出来,我们也想要把这些任务同步到本地,用Terraform来统一管理,那么可以执行如下Terraform的导入命令,来同步本地和线上的状态。
terraform import alicloud_log_etl.test-etl-job-2 test-project-1:etl_name_2
上述命令表示把Projecttest-project-1下的数据加工任务etl_name_2导入到本地Terraform的状态中。
其中test-project-1:etl_name_2是一个数据加工任务的ID,由Project名称test-project-1和数据加工的JobNameetl_name_2拼接而成,用于标识一个加工任务。test-etl-job-2是导入成功后,该任务在Terraform中的实例ID。
执行完后,如果提示Import Successful!则表示导入成功,用户可以查看Terraform工作目录下的terraform.tfstate文件内容,了解Terraform在当前环境的资产状态。