通过使用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服务。

名前テンプレートの形式対応しているクラウド提供元CloudFormationJSON, YAMLAWSのみAWSGoogle Cloud Deployment ManagerYAML, jinjaGCPのみGCPAzure Resource ManagerJSONAzureのみAzureTerraformHCLAWS, GCP, Azureなどの主要なパブリッククラウドHashiCorp

有一些只支持一个云平台的工具,也有一些支持多个云平台的工具。
本次我们将着重介绍CloudFormation和Terraform这两个工具。

4. 云形成(CFn)

4-1. 概述

CloudFormation是一项服务,它可以根据模板自动化构建AWS资源(例如: Amazon S3、Amazon EC2、AWS lambda)的过程。

4-2. 全部都一样

iac_cfn_1.drawio (1).png

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. 资源创建的步骤

iac_cfn.drawio.png
① 创建模板

这次我们将建立一个名为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
スクリーンショット 2022-11-27 14.43.25.png
差分检查(更新时)

在创建堆栈时,不会生成更改集。
关于更新时的行为,请参考第③项。

创建和更新堆栈,构建AWS资源
スクリーンショット 2022-11-27 16.23.34.png
③更新时的行为

更新堆栈时,将创建变更集。
使用以下模板,将预先创建的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

スクリーンショット 2022-11-27 16.17.42.png
スクリーンショット 2022-11-27 16.28.52.png

4-5. 在实际工作中的应用模式

iac_cfn_pipeline.drawio.png

以这种方式,可以防止以下类似的人为错误。

    • 更新対象のスタックを間違える

 

    使用するテンプレートファイルを間違える

5. 地质变迁

简介

Terraform 是 HashiCorp 公司提供的一种能够支持多云的基础设施即代码(IaC)工具。

全貌

iac_terraform_1.drawio (2).png

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. 资源创建的流程

iac_terraform.drawio.png
环境设置

由于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
  }
}
iac_terraform_pipeline.drawio (1).png

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化”。希望这篇文章可以帮助你跨过最初的障碍。

最后

我们公司不论是否有经验,都进行员工和实习生的招聘。

请点击此处查看感兴趣的内容。

广告
将在 10 秒后关闭
bannerAds