通过使用Terraform和CloudFormation学习自动化基础架构的搭建
这篇文章是Nuco Advent Calendar 2022的第11天的文章。
我打算写一下与基础设施相关的工程师必备的知识IaC。
IaC是Infrastructure as Code的缩写,也被称为”基础设施的代码化”。
最近我感觉在使用云端进行开发的时候,IaC已经变得司空见惯。
这篇文章所能得到的信息
-
- IaCの基本知識(IaCとは? なぜ使うのか? どんなツールがあるか?)
-
- CloudForamtionの全体像・使い方・サンプルコード・実務での応用例
-
- Terraformの全体像・使い方・サンプルコード・実務での応用例
- IaC導入に関するtips
1. “基础设施即代码”是什么意思?
定义
根据维基百科,IaC被定义为以下内容。
基础设施即代码(IaC)是自动化处理的过程,用于配置管理和机器可处理的定义文件的设置和供应,涵盖计算基础架构、物理服务器和虚拟服务器等。
在当代广泛普及利用云服务进行开发的情况下,对于IaC(Infrastructure as Code)的理解可以简单地认为是“通过代码管理云端服务器和配置”。
上述的”code”也有被称为”模板”或”配置文件”的情况。
IaC为什么是必要的?
2-1. 在环境建设中,可再利用性提高了。
在大多数开发现场中,至少会准备两个环境吧?
-
- prod環境(本番環境)
- dev環境(開発環境)
根据服务的性质和规模,可能需要准备除了上述环境之外的其他环境,例如stg环境。
当需要新环境时,如果手动构建,可能会增加出错的可能性,但如果采用基础设施即代码(IaC),就可以轻松创建相同的环境。
2-2. 沟通成本降低
只要记住写作方法(或者能够进行调查),内容设置已经写在文件中,即使自己不进行建设工作,也可以轻松理解内容。减少了需要向别人询问而无法解决的情况。
2-3. 可以管理更新历史
在中国,模板通常像应用程序的源代码一样使用git进行管理。
我们可以很容易地追溯到何时、由谁以及进行了怎样的更改,并且也更容易进行审查。
3. 代表性的IaC服务
我会介绍四个代表性的IaC服务。
有一些只支持一个云平台的工具,也有一些支持多个云平台的工具。
本次我们将着重介绍CloudFormation和Terraform这两个工具。
4. 云形成(CFn)
4-1. 概述
CloudFormation是一项服务,它可以根据模板自动化构建AWS资源(例如: Amazon S3、Amazon EC2、AWS lambda)的过程。
4-2. 全部都一样
4-3. Concept
4-3. 概念
在理解CloudFormation时,有三个重要的概念需要注意。
Template: 模板
Stack: 堆栈
Change set: 更改集 jí)
我们分别来看一下。
模板 (Template)
-
- 設定ファイル(AWS リソースを作成する際の設計図というイメージでokです)
-
- 1つのテンプレートに複数のAWSリソースの設定を記述できる
-
- JSON, YAML形式のテキストファイル
- 拡張子は、.json、.yaml、.yml、.template、.txt
建议使用YAML格式进行管理,这样您可以轻松添加注释。
堆栈 (Stack)
-
- 1つのテンプレートから作成されたAWSリソースの集合体
- テンプレートをCloudFormationに読み込ませると作成される
③ 修改集合(Change set)
-
- 変更差分データのこと
-
- 既存のスタックで管理されているAWSリソースの更新時に生成される
- 事前にどんな変更が反映されるかを確認することができる
4-4. 资源创建的步骤
① 创建模板
这次我们将建立一个名为nuco-advent-sample-bucket的S3存储桶作为样本。
AWSTemplateFormatVersion: "2010-09-09"
Description: template sample
Resources:
SampleBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: nuco-advent-sample-bucket
将文件上传到S3
差分检查(更新时)
在创建堆栈时,不会生成更改集。
关于更新时的行为,请参考第③项。
创建和更新堆栈,构建AWS资源
③更新时的行为
更新堆栈时,将创建变更集。
使用以下模板,将预先创建的S3存储桶设置为私有。
AWSTemplateFormatVersion: "2010-09-09"
Description: template sample
Resources:
SampleBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: nuco-advent-sample-bucket
PublicAccessBlockConfiguration: # 追加
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
4-5. 在实际工作中的应用模式
以这种方式,可以防止以下类似的人为错误。
-
- 更新対象のスタックを間違える
- 使用するテンプレートファイルを間違える
5. 地质变迁
简介
Terraform 是 HashiCorp 公司提供的一种能够支持多云的基础设施即代码(IaC)工具。
全貌
5-3. 概念:理念/概念/观念
在理解Terraform时,重要的概念有以下四个:
1. tf文件
2. tfstate文件(terraform.tfstate)
3. Terraform核心
4. Terraform插件
TF文件
-
- 構築するリソースを定義する設定ファイルのこと
開発者が作成するファイル
HCL (HashiCorp Configuration Language)という言語で記述する
拡張子は.tf
tfstate文件
-
- Terraformに認識されているリソースの状態が定義されたファイル
Terraformによって生成されるファイル
拡張子は.tfstate
デフォルトのファイル名は、terraform.tfstate
③Terraform 核心
-
- Go言語で書かれたCLI
-
- tfファイルの作成後にterraformコマンドを使うことで実行される
-
- tfファイルとtfstateファイルを受け取り、差分を確認し、構築・変更するリソースの状態を決める
-
- Terraform Pluginsに対して、リソースに関する操作をリクエストする
Terraform v0.12からプロトコルv5になり、gRPCを採用
④ Terraform 插件
-
- Terraform Coreから呼び出されるプログラム
-
- AWSやGCPといった個別のプロバイダに対してリソースの構築や破棄に関する操作を行う
-
- Pluginsを構成する要素として、ProviderとProvisinoerがある
Provider
AWSやGCPのリソースの作成, 更新, 削除に関する操作をするためのプラグイン
Provisinoer
作成したリソースを操作(ex. サーバーの設定)するためのプラグイン
5-4. 资源创建的流程
环境设置
由于Terraform Core会在本地环境中运行插件,所以需要进行环境配置。
安装Terraform(针对Mac用户)。
% brew install tfenv
% tfenv install 1.3.5
% tfenv use 1.3.5
创建tf文件
目录结构如下所示。
作業ディレクトリ/
├ providers.tf # providerの情報を設定
├ sample.tf # 後ほどS3のリソースを定義
因为我们要在AWS环境中构建资源,所以要设置”provider: “aws””。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "= 4.40.0"
}
}
required_version = "1.3.5"
}
provider "aws" {
region = "ap-northeast-1"
profile = "xxxx" # awsの認証情報を設定
}
resource "aws_s3_bucket" "nuco-advent-sample-bucket-tf" {
bucket = "nuco-advent-sample-bucket-tf"
}
resource "aws_s3_bucket_public_access_block" "nuco-advent-sample-bucket-tf" {
bucket = aws_s3_bucket.nuco-advent-sample-bucket-tf.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
执行Terraform命令
开始
-
- terraformの設定を初期化するためのコマンド
-
- terraform init を実行すると、providers.tf で設定している plugin(aws provider)がダウンロードされる
- ダウンロードされたファイルは、コマンドを実行したディレクトリの .terraform内に配置される
AWS_PROFILE=xxxx terraform init
计划
-
- 作成予定のリソースを確認するためのコマンド
- planを実行すると、Terraform Core側でtfファイルとtfstateファイルが比較され、更新対象のリソースが決まる
AWS_PROFILE=xxxx 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:
# aws_s3_bucket.nuco-advent-sample-bucket-tf will be created
+ resource "aws_s3_bucket" "nuco-advent-sample-bucket-tf" {
+ acceleration_status = (known after apply)
+ acl = (known after apply)
+ arn = (known after apply)
+ bucket = "nuco-advent-sample-bucket-tf"
+ bucket_domain_name = (known after apply)
(中略)
# aws_s3_bucket_public_access_block.nuco-advent-sample-bucket-tf will be created
+ resource "aws_s3_bucket_public_access_block" "nuco-advent-sample-bucket-tf" {
+ block_public_acls = true
+ block_public_policy = true
+ bucket = (known after apply)
+ id = (known after apply)
+ ignore_public_acls = true
+ restrict_public_buckets = true
}
Plan: 2 to add, 0 to change, 0 to destroy.
在实际工作中,有时候会在计划通过阶段进行评审。
申请
-
- リソースを作成するためのコマンド
- applyを実行するとTerrafomr CoreからProviderに対して、リソース操作のリクエストがされる
AWS_PROFILE=xxxx terraform apply
因为被问到类似的问题,所以输入yes。
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
申请的结果
aws_s3_bucket.nuco-advent-sample-bucket-tf: Creating...
aws_s3_bucket.nuco-advent-sample-bucket-tf: Creation complete after 3s [id=nuco-advent-sample-bucket-tf]
aws_s3_bucket_public_access_block.nuco-advent-sample-bucket-tf: Creating...
aws_s3_bucket_public_access_block.nuco-advent-sample-bucket-tf: Creation complete after 0s [id=nuco-advent-sample-bucket-tf]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
在这个时机,将会在本地环境创建terraform.tfstate文件。
{
"version": 4,
"terraform_version": "1.3.5",
"serial": 3,
"lineage": "daa61021-d26d-a4ee-a299-9c6545780fff",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_s3_bucket",
"name": "nuco-advent-sample-bucket-tf",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"acceleration_status": "",
"acl": null,
"arn": "arn:aws:s3:::nuco-advent-sample-bucket-tf",
"bucket": "nuco-advent-sample-bucket-tf",
5-5. 在实际工作中的使用方式
为了实时共享terraform.tfstate,我们可以使用名为backend的功能,并通过S3存储桶来管理terraform.tfstate。
在这种情况下,providers.tf将如下所示。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "= 4.40.0"
}
}
required_version = "1.3.5"
backend "s3" { # 追加
bucket = "nuco-advent-terraform-state"
region = "ap-northeast-1"
key = "sample/terraform.tfstate"
encrypt = true
}
}
6. 关于IaC的注意事项
当然,基础设施即代码(IaC)也存在一些缺点。
6-1. 学习需要花费成本。
正如这个样本所显示的,即使是相同设置的S3存储桶,模板编写方式和构建步骤也因服务而异。
我认为并不一定“现在的项目是AWS环境,所以只能选择CFn!”而是“所有基础设施负责人都能使用Terraform,将使未来的分配更加容易”,也是一个可以考虑的选择。
6-2. 对于现有系统的处理方案是什么?
如果系统尚未进行 IaC 支持的话,是不是从现在开始就该考虑进行 IaC 支持呢?
我认为,如果您有足够的验证期来进行,且能从长远来看受益于 IaC 支持,那么进行相应的支持是可以的。
6-3. 基础架构即代码(IaC)并不始终高效。
举例如下,在一些情况下,可能会选择不故意地进行IaC适配。
-
- 新しいAWSサービスをちょっと試してみたい
- PoC開発(コンセプト検証)のためのサンプルを作りたい
在AWS环境下,验证时可以通过管理控制台创建资源,然后通过CFn等工具将其转化为基础设施即代码(IaC)。
总结
使用CloudFormation和Terraform的示例,我尝试解释了IaC。
起初可能会感到有些麻烦,但当要管理的资源数量增加时,你会觉得”噢,真庆幸进行了IaC化”。希望这篇文章可以帮助你跨过最初的障碍。
最后
我们公司不论是否有经验,都进行员工和实习生的招聘。
请点击此处查看感兴趣的内容。