我总结了关于Terraform最佳实践、工作空间和模块化的思路(针对AWS提供者)

我是。
最强的《Terraform》玩家大家晚上好。
好久没有玩《Terraform》了,最近又迷上了使用workspace和module进行apply,所以整理了一些心得。

对应版本

    • 本体: terraform v0.11.1

 

    provider: aws v1.5.0

使用Terraform根据我的归纳结论

Terraform非常简单易用。

我仍然是那个能够灵活运用Workspace和Module的terraform新兵。更准确地说,我已经深入接触得太多,无法离开了,哈哈哈。不考虑思维方式,随意跳过吧。

思考方式

    • 全部寺したいかたは寺どうぞ。

 

    terraformは文学, CloudFormationは芸術, プルリクは人生, コードレビューは友情です。

建立环境

    • 設計思想やModule仕様をまとめたDocumentを常々更新するパワーがない

 

    チームメンバーに伝達して一定品質保てるようなパワーがなければ素のterraformが楽です

利用

    • 全部寺でもいいけどLaunch/create/attach/destroyする、に留めるのがよいです

 

    • ルールの更新については俺達のCodenize.toolsで補えるものはこっちに寄せる方がRuby DSLによる表現力の高さや強力なDry-Runの恩恵を受けることができます。最高。

 

    stateを持つコンポーネントであるRDSやElastiCache周りの構成変更はDestory判定から逃れられないものが多いのでCLIが安牌です

将ElastiCache Redis复制组成员从单可用区(Single-AZ)更改为多可用区(Multi-AZ)。

    • 1nodeのreplication group作成

 

    number of nodeを1->2にするとDestroy -> Create判定になる

最后,我选择的最强terraform设计是什么?

    Workspaceと異なり視覚効果に優れた方針を最強Opsの@shiruさんが公開してくれている。いきなりWorkspace/Moduleへ手を出す前に俺はコッチのほうをオススメしたい

如果还想要使用Workspace和Module的话,那么就继续往下看吧!

关于工作空间

terraform_workspace.png

通过在资源内添加 `${terraform.env}`,在执行 plan/apply 时可以读取当前工作区的名称,从而减少冗余的代码。在上面的图例中,通过将建设/运营目标环境放入工作区中,可以将计划/应用执行的配置更改目标限制在环境级别。

建议阅读ssh絶対殺すマン@shogomuranushi的《2017年Terraform最佳实践》以了解详细信息。

Workspace的实现方法

由于我是EC2的初学者,所以我会专注于VPC的实施方法。
这次的内容不涉及地区的问题。
如果是多地区构建,可能会涉及到其他Workspace的思考方式。

難易度俺俺名称VPCの状態環境分離の方法低専用テナント型環境ごとにVPCが分離されている場合develop/stage/productionといった名称のVPCで環境が分離されている高共有テナント型環境がVPCで分離されていない1VPCとしてセキュリティグループレベルで環境が分離されている

专用租户模式

dedicated_workspace.png

如果可以将资源在整个环境中均匀分配,那么这是最简单的方式。
只需在切换工作区后计划并应用即可。

terraform workspace new <環境名>
terraform workspace select <環境名>
module "ad" {
    source = "../../modules/provider/aws/ec2"
    ec2 = "${var.ad}"
    iam_instance_profile = "${data.terraform_remote_state.iam.activedirectory["name"]}"
    subnet_id = "${data.terraform_remote_state.network.vpc.${terraform.env}.protected-route-nat-a}"
    vpc_security_group_ids = ["${data.terraform_remote_state.network.common["id"]}",
                              "${data.terraform_remote_state.network.ad["id"]}"]
}

多个商户共用的租户模式

shared_workspace.png

如果在1VPC中创建多个环境并通过SG进行隔离,可以切换工作区,在plan->apply过程中进行。但是在调用共享租户时,请不要写${terraform.env}。

terraform workspace new <環境名>
terraform workspace select <環境名>

在★的地方直接指定存在共享租户的工作区名称,而不需要指定${terraform.env}。

module "ad" {
    source = "../../modules/provider/aws/ec2"
    ec2 = "${var.ad}"
    iam_instance_profile = "${data.terraform_remote_state.iam.activedirectory["name"]}"
★    subnet_id = "${data.terraform_remote_state.network.vpc.prod.protected-route-nat-a}"
    vpc_security_group_ids = ["${data.terraform_remote_state.network.common["id"]}",
                              "${data.terraform_remote_state.network.ad["id"]}"]
}

关于模块

我对模块化到什么程度有些犹豫。
不是所有东西都适合模块化。
最好确定好模块化的程度。
我希望在2个层级上进行模块化。

公共模块

实体。俗称外表的定义。
表示可以向第三方公开的定义。可在github.com等平台上公开。
资源示例:aws_vpc、aws_subnet、aws_instance、aws_eip等。

私有模块

表示具有包含环境固有信息的属性。
可在github.com的私有存储库或github企业上进行管理。
在terraform中,最好将不能将框架和属性分开定义的内容作为私有模块处理。

资源示例:aws_security_group_rule,aws_elb等。定义了对外表现的内部内容。
SG(包含企业IP的定义)以私有模块的形式进行管理,可重复使用并简化维护。
※ 由于aws_elb无法将ELB和监听器分离创建,因此将其私有模块化是个好选择。

做得好,模块。

最初からモジュール化してはならないものは、
実体と属性の関連付けを行うリソースです。
リソースの例には、aws_elb_attachment、aws_eip_associationなどがあります。

模块的调用示例

    実体のvariable
variable "ad" {
    type = "map"
    default = {
        prod.ami = "ami-ec279c8a"  # Windows 2016
        prod.key_name = "XXXXXXXx"
        prod.public_key = "**********"
        prod.instance_type = "t2.medium"
        prod.iam_instance_profile = "ad"
        prod.source_dest_check = true
        prod.ebs_optimized = false
        prod.root_block_device = "gp2"
        prod.root_block_device_size = 64
        prod.ec2_count = 1
        prod.eip_count = 0
        prod.tag_name = "ad"
        prod.tag_role = "ad"
        prod.tag_amirotate = ""
    }
}
variable "ad_elb" {
    type = "map"
    default = {
        prod.name = "ad-elb"
        prod.instance_port = "3389"
        prod.availability_zones = ["ap-northeast-1a","ap-northeast-1c"]
        prod.access_logs_bucket = "XXXXXXXXXXX"
        prod.access_logs_bucket_prefix = ""
        prod.instance_protocol = "tcp"
        prod.lb_port = 3389
        prod.lb_protocol = "tcp"
        prod.lb_healthcheck_interval = 30
        prod.healthy_threshold = 2
        prod.unhealthy_threshold = 3
        prod.lb_target_timeout = 15
        prod.lb_healthcheck_interval = 5
        prod.cross_zone_load_balancing = true
        prod.idle_timeout = 60
        prod.connection_draining = 10
        prod.connection_draining_timeout = 15
    }
}
    実体の作成と関連付け
module "ad" {
    source = "../../modules/provider/aws/ec2"
    ec2 = "${var.ad}"
    iam_instance_profile = "${data.terraform_remote_state.iam.activedirectory["name"]}"
    subnet_id = "${data.terraform_remote_state.network.vpc.prod.protected-route-nat-a}"
    vpc_security_group_ids = ["${data.terraform_remote_state.network.common["id"]}",
                              "${data.terraform_remote_state.network.ad["id"]}"]
}

module "ad_elb" {
    source = "../../modules/provider/aws/loadbalancer/elb"
    elb = "${var.ad_elb}"
}

resource "aws_elb_attachment" "ad" {
  elb      = "${module.ad_elb.id}"
  instance = "${module.adelb.id}"
}

我认为只需要这个模组就可以过上不会太过努力的人生。

工作区和模块的图解

workspace_and_module.png

我认为,如果你想从零开始学习terraform,并且希望逐渐摆脱原始的terraform设计,那么你可以先通过具有较高可读性的shiru式terraform设计进行熟悉,然后逐步探索workspace和module。虽然workspace和module可能不容易理解,但这是一个很好的方向。通过考虑事故风险,你可以将其连接到一个不错的terraform设计中。

那么,让我们开始美妙的Terraform生活吧!

完成

广告
将在 10 秒后关闭
bannerAds