Terraformを使用する際のベストプラクティス[終了]


111

現在、インフラストラクチャをテラフォームにスワップしています。Terraformファイルと状態を実際に管理するためのベストプラクティスは何ですか?コードとしてのインフラストラクチャであることに気付き、.tfファイルをgitにコミットしますが、tfstateもコミットしますか?それはS3のような場所にあるべきですか?最終的にCIでこれらすべてを管理できるようにしたいのですが、それははるかに広範であり、ファイルの移動部分を把握する必要があります。

実はこのタイプの製品を実際にどのように利用しているのか見てみたいと思っています

回答:


85

私はまた、既存のAWSインフラストラクチャをTerraformに移行する状態にあります。開発中に回答を更新することを目指します。

私は、Terraformの公式のと、不確かな領域を具体化するための複数の試行錯誤に大きく依存しています。

.tfstate ファイル

Terraform configを使用して、さまざまなインフラストラクチャに多くのボックスをプロビジョニングできます。複数のユーザーが実行することもできるため、この状態は中央の場所(S3など)にある必要がありますが gitではありません

これはTerraformを確認すると確認できます.gitignore

開発者による制御

私たちの目的は、完全な監査(gitログ)を維持しながら、インフラストラクチャのより多くの制御を開発者に提供し、変更を正常性チェックする機能(プルリクエスト)を提供することです。そのことを念頭に置いて、私が目指している新しいインフラストラクチャワークフローは次のとおりです。

  1. 人形などの再利用可能なモジュールを含む一般的なAMIの基盤。
  2. Terraformを使用してDevOpsによってプロビジョニングされたコアインフラストラクチャ。
  3. 開発者は必要に応じてGitでTerraform設定を変更します(インスタンスの数、新しいVPC、リージョン/可用性ゾーンの追加など)。
  4. DevOpsチームのメンバーによって、Git構成がプッシュされ、プルリクエストが送信され、正常性チェックが行われます。
  5. 承認された場合、CIにwebhookを呼び出してビルドとデプロイを行います(現時点で複数の環境をパーティション分割する方法は不明です)

編集1-現在の状態で更新

この回答を始めてから、私は多くのTFコードを記述し、私たちの状況でより快適に感じています。途中でバグや制限に遭遇しましたが、これは、急速に変化する新しいソフトウェアを使用する特徴であることを認めます。

レイアウト

それぞれに複数のサブネットを持つ複数のVPCを持つ複雑なAWSインフラストラクチャがあります。これを簡単に管理するための鍵は、インフラストラクチャコード(テラフォームとパペットの両方)を整理するために使用できる地域、環境、サービス、所有者を含む柔軟な分類法を定義することでした。

モジュール

次のステップは、Terraformモジュールを格納する単一のgitリポジトリを作成することでした。モジュールの最上位のdir構造は次のようになります。

tree -L 1 .

結果:

├── README.md
├── aws-asg
├── aws-ec2
├── aws-elb
├── aws-rds
├── aws-sg
├── aws-vpc
└── templates

それぞれがいくつかの健全なデフォルトを設定しますが、それらを「接着剤」で上書きできる変数として公開します。

接着剤

glue上記のモジュールを利用する2番目のリポジトリがあります。これは、分類法ドキュメントに沿ってレイアウトされています。

.
├── README.md
├── clientA
   ├── eu-west-1
      └── dev
   └── us-east-1
       └── dev
├── clientB
   ├── eu-west-1
      ├── dev
      ├── ec2-keys.tf
      ├── prod
      └── terraform.tfstate
   ├── iam.tf
   ├── terraform.tfstate
   └── terraform.tfstate.backup
└── clientC
    ├── eu-west-1
       ├── aws.tf
       ├── dev
       ├── iam-roles.tf
       ├── ec2-keys.tf
       ├── prod
       ├── stg
       └── terraform.tfstate
    └── iam.tf

クライアントレベルの内部には、.tfグローバルリソース(IAMロールなど)をプロビジョニングするAWSアカウント固有のファイルがあります。次は、EC2 SSH公開鍵を使用したリージョンレベルです。最後に、私たちの環境(でdevstgprodなど)私たちのVPCのセットアップ、インスタンスの作成とピアリングの接続などが格納されています。

補足:ご覧のとおり、私terraform.tfstateはgitを維持することよりも自分のアドバイスに反対しています。これは私がS3に移行するまでの一時的な措置ですが、私が現在唯一の開発者なので、私に適しています。

次のステップ

これはまだ手動プロセスであり、まだJenkinsではありませんが、かなり大規模で複雑なインフラストラクチャを移植しており、これまでのところ非常に優れています。私が言ったように、いくつかのバグがうまくいきます!

編集2-変更

この最初の回答を書いてからほぼ1年が経ち、Terraformと私自身の状況は大きく変化しました。現在、Terraformを使用してAzureクラスターを管理する新しいポジションにいますが、Terraformは今v0.10.7です。

状態

人々は繰り返し私に、状態はGitに入れるべきではないと言ってきました-そしてそれらは正しいです。私たちはこれを、開発者のコ​​ミュニケーションと規律に依存する2人のチームとの暫定措置として使用しました。より大規模な分散型チームにより、S3のリモート状態を完全に活用し、DynamoDBが提供するロックを使用しています。理想的には、これは領事に移行され、クロスクラウドプロバイダーを削減するのはv1.0です。

モジュール

以前は、内部モジュールを作成して使用していました。これはまだ事実ですが、Terraformレジストリの出現と成長に伴い、これらを少なくともベースとして使用するようにしています。

ファイル構造

新しいポジションには、2つのinfx環境のみが含まれる、より単純な分類法がdevありprodます。それぞれに独自の変数と出力があり、上記で作成したモジュールを再利用します。remote_stateまた、プロバイダは、環境間で作成されたリソースの出力を共有するのに役立ちます。私たちのシナリオは、グローバルに管理されているTLDに対するさまざまなAzureリソースグループのサブドメインです。

├── main.tf
├── dev
   ├── main.tf
   ├── output.tf
   └── variables.tf
└── prod
    ├── main.tf
    ├── output.tf
    └── variables.tf

企画

ここでも、分散チームの追加の課題があるため、常にterraform planコマンドの出力を保存します。planapplyステージの間で変更を加えることなく、何が実行されるかを検査して知ることができます(ただし、ロックはこれに役立ちます)。プレーンテキストの「シークレット」変数が含まれている可能性があるため、このプランファイルは必ず削除してください。

全体的に、Terraformに非常に満足しており、新しい機能が追加されて学習と改善が続けられています。


この回答以来、運/問題はありましたか?あなたのものは私が目指していることと非常に似ているようですが、あなたは私よりも遠くにいるかもしれません。
マークヤング

3
tfstateファイルをgitに保存してはならない理由を知りたいのですが。それは単に古い状態が保存する価値がないからですか、それとも他の問題がありますか?
agbodike

3
@agbodike-単一の開発者または非常に小さなチームの一部として作業している場合、競合を回避するために定期的にコミットおよびプッシュされる限り、tfstateをgitに保持できます。私の次のステップは、これをS3のリモート状態ドキュメントに従ってセットアップすることです(これは、「マージの競合の頻繁な原因であるため、チーム内でTerraformを使用することを複雑にします。リモート状態は、これらの問題を軽減するのに役立ちます。」) 。ほとんどの場合と同様に、良好なチームコミュニケーションは、状態を保持するための戦術に関係なく、ほとんど/すべての問題を軽減するのに役立ちます:-)
Ewan

1
@ the0ther-私のメインリポジトリはプロプライエタリであると思いますが、現在、個人向けのものに取り組んでおり、近い将来に公開する予定です。
ユアン

2
Gitリポジトリ@Ewanでの運は?あなたが何をしているか見てみたいです。
David

85

Terraformを多用しており、推奨セットアップは次のとおりです。

ファイルレイアウト

各環境(stage、prod、qaなど)のTerraformコードを個別のテンプレートセット(したがって個別の.tfstateファイル)に保存することを強くお勧めします。これは重要です。変更を行う間、個別の環境は実際には互いに分離されています。そうしないと、ステージングでコードをいじりながら、prodで何かを爆破するのは簡単すぎます。Terraform、VPC、およびなぜ環境ごとのtfstateファイルが必要なのか、理由についてのカラフルな説明を参照してください。

したがって、一般的なファイルレイアウトは次のようになります。

stage
   main.tf
   vars.tf
   outputs.tf
prod
   main.tf
   vars.tf
   outputs.tf
global
   main.tf
   vars.tf
   outputs.tf

ステージVPCのすべてのTerraformコードがstageフォルダーに入れられ、製品VPCのすべてのコードがprodフォルダーに入れられ、VPCの外部にあるすべてのコード(IAMユーザー、SNSトピック、S3バケットなど)がglobalフォルダーに入れられます。

慣例により、通常、Terraformコードを3つのファイルに分割します。

  • vars.tf:入力変数。
  • outputs.tf:出力変数。
  • main.tf:実際のリソース。

モジュール

通常、インフラストラクチャは2つのフォルダで定義します。

  1. infrastructure-modules:このフォルダーには、小さく、再利用可能な、バージョン管理されたモジュールが含まれています。各モジュールは、VPCやデータベースなどのインフラストラクチャの単一部分を作成する方法の青写真と考えてください。
  2. infrastructure-live:このフォルダには、実際に稼働している実行中のインフラストラクチャが含まれています。このインフラストラクチャは、のモジュールを組み合わせて作成しますinfrastructure-modules。このフォルダー内のコードは、設計図から構築した実際の家と考えてください。

テラフォームモジュールは、フォルダ内のテラフォームテンプレートのただのセットです。たとえば、単一のVPCのすべてのルートテーブル、サブネット、ゲートウェイ、ACLなどを定義すると呼ばれるフォルダーがあるとvpcしますinfrastructure-modules

infrastructure-modules
   vpc
     main.tf
     vars.tf
     outputs.tf

次に、そのモジュールをinfrastructure-live/stageinfrastructure-live/prodで使用して、ステージVPCと製品VPCを作成します。たとえば、次のinfrastructure-live/stage/main.tfようになります。

module "stage_vpc" {
  source = "git::git@github.com:gruntwork-io/module-vpc.git//modules/vpc-app?ref=v0.0.4"

  vpc_name         = "stage"
  aws_region       = "us-east-1"
  num_nat_gateways = 3
  cidr_block       = "10.2.0.0/18"
}

モジュールを使用するには、moduleリソースを使用して、そのsourceフィールドにハードドライブのローカルパス(例source = "../infrastructure-modules/vpc":)、または上記の例のようにGit URL(モジュールソースを参照)を指定します。Git URLの利点は、特定のgit sha1またはタグ(ref=v0.0.4)をです。これで、インフラストラクチャを小さなモジュールの集まりとして定義するだけでなく、それらのモジュールにバージョンを付け、必要に応じて慎重に更新またはロールバックすることができます。

再利用、テスト、および文書化された多数のインフラストラクチャパッケージを作成しましたVPC、Dockerクラスター、データベースなどを作成するためにを作成しました。内部では、それらのほとんどがバージョン付きのTerraformモジュールです。

状態

Terraformを使用してリソース(EC2インスタンス、データベース、VPCなど)を作成すると、作成したものに関する情報が.tfstateファイルに記録されます。これらのリソースを変更するには、チームの全員.tfstateが同じファイルにアクセスする必要がありますが、Gitにチェックインしないでください(理由の説明については、こちらを参照してください)。

代わりに、Terraform Remote Stateを.tfstate有効にしてS3にファイルを保存することをお勧めします。これにより、Terraformを実行するたびに最新のファイルが自動的にプッシュ/プルされます。S3バケットでバージョニング有効にして.tfstate、最新バージョンが破損した場合に古いファイルにロールバックできるようにしてください。ただし、重要な注意:Terraformはロックを提供しません。そのため、2人のチームメンバーがterraform apply同じ.tfstateファイルで同時に実行すると、お互いの変更が上書きされる可能性があります。

この問題を解決するために、Terraruntと呼ばれるオープンソースツールを作成しました。これは、Amazon DynamoDBを使用してロックを提供するTerraformのシンラッパーです(ほとんどのチームにとって完全に無料です)。詳細については、Terragruntを使用してTerraformに自動リモート状態ロックと構成を追加するをご覧ください。

参考文献

実世界でTerraformを使用するために学んだすべてのベストプラクティスを詳細に説明する一連のブログ投稿「A Terreformの包括的なガイド」を開始しました。

更新:Terraformブログの投稿シリーズの包括的なガイドが非常に人気になり、Terraform:Up&Runningと呼ばれる本に拡大しました


これが正解だと思います。モジュールを使用し、バージョンを付け、環境を分離します。
ラングラー

テラグラントや他のラッパーを使用していない場合でも、別のterraformコンポーネント/環境/モジュール/その他で作業するたびに、リモート構成ステップを再実行する必要がありますか?
jmreicha

@jmreicha:remote configTerraform構成をチェックアウトしたばかりの場合、または以前のリモート構成を変更したい場合は、実行する必要があります。Terraform 0.9では、の概念が導入されbackends、これにより多くのことが簡素化されます。詳細については、このPRを参照してください。
Yevgeniy Brikman 2017

私が理解しているように-私は環境「ステージ」で作業していますが、その後「製品」で作業を開始します。remote configprod状態を指すようにコマンドを再実行する必要があります。環境ごとに異なる状態を想定しています。そうですか?v0.9を楽しみにしています。
jmreicha 2017

まったく同じ.tfファイルのセットを2つの異なる環境にデプロイする場合は、はい、remote config切り替えるたびに実行する必要があります。これは明らかに非常にエラーが発生しやすいので、この手法を実際に使用することはお勧めしません。代わりに、チェックアウトこのブログの記事で推奨テラフォームファイルのレイアウトを一緒にこのブログの記事でテラフォームモジュールを使用する方法
Yevgeniy Brikman 2017

9

以前remote configはこれを許可していましたが、現在は " バックエンド "に置き換えられているため、Teraformリモートは使用できなくなりました。

terraform remote config -backend-config="bucket=<s3_bucket_to_store_tfstate>" -backend-config="key=terraform.tfstate" -backend=s3
terraform remote pull
terraform apply
terraform remote push

詳細はドキュメントを参照してください。


別のTerraformコンポーネント/環境/モジュール/その他で作業するたびに、リモートソースを再構成する必要がありますか?
jmreicha 2017

6

@Yevgeny Brikmanでより詳細に説明されていますが、特にOPの質問に答えています。

Terraformファイルと状態を実際に管理するためのベストプラクティスは何ですか?

TFファイルにはgitを使用します。ただし、状態ファイル(tfstateなど)はチェックしないでください。代わりにTerragrunt、S3への状態ファイルの同期/ロックに使用します。

しかし、tfstateもコミットしますか?

番号。

それはS3のような場所にあるべきですか?

はい


2

私はここに多くの答えがあることを知っていますが、私のアプローチはかなり異なります。

   Modules
   Environment management 
   Separation of duties

モジュール

  1. リソースの論理コレクションのモジュールを作成します。例:DB、HA VM、自動スケーリング、DNS、PubSub、オブジェクトストレージを必要とするAPIをデプロイすることが目標の場合、これらすべてのリソースを単一のモジュールでテンプレート化する必要があります。
  2. 単一のリソースを利用するモジュールを作成しないでください。これは実行可能であり、実行済みであり、レジストリ内の多くのモジュールがこれを実行しますが、インフラストラクチャオーケストレーションではなく、リソースへのアクセスを支援する方法です。例:AWS EC2のモジュールは、複雑な構成をより簡単に呼び出せるようにすることで、ユーザーがEC2にアクセスするのを助けますが、1の例のようなモジュールは、アプリケーション、コンポーネント、またはサービス駆動型インフラストラクチャを調整するときにユーザーを支援します。
    1. ワークスペースでのリソース宣言は避けてください。これは、コードを整頓して整理することを目的としています。モジュールは簡単にバージョン管理されるため、リリースをより細かく制御できます。

環境管理

IaCにより、SDLCプロセスがインフラストラクチャ管理に関連するようになりました。開発アプリケーション環境だけでなく開発インフラストラクチャも期待できません。

  1. IaC環境の管理にフォルダーを使用しないでください。インフラストラクチャに共通のテンプレートがないため、これはドリフトにつながります。
  2. 単一のワークスペースと変数を使用して、環境仕様を制御してください。例:環境変数を変更すると(var.stageが一般的)、要件に合わせて計画が変更されるようにモジュールを記述します。通常、環境の変化はできるだけ少なくする必要があり、量、露出、容量は通常可変構成です。開発では、プライベートトポロジに1コアと1 GBのRAMを備えた1つのVMを展開する場合がありますが、本番環境は、追加のパブリックトポロジを備えた2コアと4 GBのRAMを備えた3つのVMです。もちろん、より多くのバリエーションを用意することもできます。開発者は、アプリケーションと同じサーバーでデータベースプロセスを実行してコストを節約できますが、本番環境には専用のDBインスタンスがある場合があります。これらすべては、単一の変数、三項ステートメント、および補間を変更することで管理できます。

職務の分離

小規模な組織や個人のインフラストラクチャを実行している場合、これは実際には当てはまりませんが、運用の管理に役立ちます。

  1. インフラストラクチャを職務、責任、またはチームごとに分類します。例:中央ITが基盤となる共有サービス(仮想ネットワーク、サブネット、パブリックIPアドレス、ロググループ、ガバナンスリソース、マルチテナントDB、共有キーなど)を制御する一方で、APIチームはサービスに必要なリソース(VM、LB)のみを制御します、PubSubなど)、データソースとリモートの状態ルックアップを通じて中央ITサービスを利用します。
    1. チームアクセスを管理します。例:中央ITは管理者権限を持っている可能性がありますが、APIチームは制限されたパブリッククラウドAPIのセットにしかアクセスできません。

一部のリソースはめったに変更されず、他のリソースは常に変更されるため、これはリリースの問題にも役立ちます。分離はリスクと複雑さを取り除きます。

この戦略は、AWSのマルチアカウント戦略と類似しています。詳細については、読んでください。

CI / CD

これはそれ自体のトピックですが、Terraformは優れたパイプライン内で非常にうまく機能します。ここで最も一般的なエラーは、CIを特効薬として扱うことです。技術的には、Terraformは、アセンブリパイプラインの段階でのみインフラストラクチャをプロビジョニングする必要があります。これは、通常はテンプレートを検証およびテストするCIステージで発生することとは別のものです。

注意:モバイルで書かれているため、エラーを許しません。


0

回答が非常に堅固で有益になる前に、ここに2セントを追加してみます

コードを構造化するための一般的な推奨事項

  1. 少数のリソースで作業する方が簡単で高速です。

    • コマンドterraform planterraform適用の両方が、リソースのステータスを確認するためにクラウドAPI呼び出しを行います。
    • インフラストラクチャ全体が1つの構成に含まれている場合、同じフォルダーに複数のファイルがある場合でも、これには数分かかることがあります。
  2. ブラスト半径は、リソースが少ないほど小さくなります。

    • 無関係なリソースを別々のコンポジション(フォルダー)に配置することにより、それらを互いに隔離することで、問題が発生した場合のリスクを軽減します。
  3. リモート状態を使用してプロジェクトを開始します。

    • あなたのラップトップは、真実のインフラストラクチャのソースのための場所ではありません。
    • tfstategitでファイルを管理することは悪夢です。
    • その後、インフラストラクチャレイヤーが任意の方向(依存関係またはリソースの数)に成長し始めるとき。
    • サンプルモジュール:https : //github.com/cloudposse/terraform-aws-tfstate-backend
    • refツール:https : //github.com/camptocamp/terraboard
  4. 一貫した構造と命名規則を実践してみてください。

    • 手続き型コードと同様に、Terraformコードは、最初に読む人のために作成する必要があります。6か月後に変更が発生した場合、一貫性が役立ちます。
    • Terraform状態ファイルでリソースを移動することは可能ですが、構造と命名に一貫性がないと、実行が難しくなる場合があります。
  5. リソースモジュールをできるだけわかりやすくします。

  6. 変数として渡したり、データソースを使用して検出したりできる値をハードコーディングしないでください。

  7. dataソースを使用し、terraform_remote_state特にコンポジション内のインフラストラクチャモジュール間の接着剤として使用します。

参照記事: https : //www.terraform-b​​est-practices.com/code-structure


例:

少数のリソースで作業する方が簡単で高速なので、以下に推奨コードレイアウトを示します。

注:各プロジェクトには固有の特性があるため、厳密には従わないように参照してください

.
├── 1_tf-backend #remote AWS S3 + Dynamo Lock tfstate 
   ├── main.tf
   ├── ...
├── 2_secrets
   ├── main.tf
   ├── ...
├── 3_identities
   ├── account.tf
   ├── roles.tf
   ├── group.tf
   ├── users.tf
   ├── ...
├── 4_security
   ├── awscloudtrail.tf
   ├── awsconfig.tf
   ├── awsinspector.tf
   ├── awsguarduty.tf
   ├── awswaf.tf
   └── ...
├── 5_network
   ├── account.tf
   ├── dns_remote_zone_auth.tf
   ├── dns.tf
   ├── network.tf
   ├── network_vpc_peering_dev.tf
   ├── ...
├── 6_notifications
   ├── ...
├── 7_containers
   ├── account.tf
   ├── container_registry.tf
   ├── ...
├── config
   ├── backend.config
   └── main.config
└── readme.md

0

インフラストラクチャを調整するためにterraformを使用する際に従う必要があるベストプラクティスはほとんどないと思います

  1. 同じコードを再度記述しないでください(再利用性)
  2. 簡単に保守できるように、環境構成を分けてください。
  3. リモートバックエンドs3(暗号化)とダイナモDBを使用して同時ロックを処理する
  4. モジュールを作成し、メインインフラストラクチャでそのモジュールを複数回使用します。これは、異なるパラメーターを渡すことで複数回呼び出すことができる再利用可能な関数のようなものです。

複数の環境に対応

ほとんどの場合、推奨される方法はterraformの「ワークスペース」を使用して複数の環境を処理することですが、ワークスペースの使用法は組織の作業方法によって異なる可能性があると思います。その他は、環境の状態を分離するために、各環境(ステージ、製品、QAなど)のTerraformコードを格納します。ただし、この場合、多くの場所で同じコードをコピーしているだけです。

├── main.tf
├── dev
   ├── main.tf
   ├── output.tf
   └── variables.tf
└── prod
├── main.tf
├── output.tf
└── variables.tf

ほとんどの場合、すべての環境は90%同一であると信じているので、いくつかの異なるアプローチに従って、各環境フォルダーに保持することで、同じterraformコードの重複を処理および回避しました。

├── deployment
 ├── 01-network.tf
 ├── 02-ecs_cluster.tf
 ├── 03-ecs_service.tf
 ├── 04-eks_infra.tf
 ├── 05-db_infra.tf
 ├── 06-codebuild-k8s.tf
 ├── 07-aws-secret.tf
 ├── backend.tf
 ├── provider.tf
 └── variables.tf
├── env
 ├── dev
  ├── dev.backend.tfvar
  └── dev.variables.tfvar
 └── prod
 ├── prod.backend.tfvar
 └── prod.variables.tfvar
├── modules
 └── aws
 ├── compute
  ├── alb_loadbalancer
  ├── alb_target_grp
  ├── ecs_cluster
  ├── ecs_service
  └── launch_configuration
 ├── database
  ├── db_main
  ├── db_option_group
  ├── db_parameter_group
  └── db_subnet_group
 ├── developertools
 ├── network
  ├── internet_gateway
  ├── nat_gateway
  ├── route_table
  ├── security_group
  ├── subnet
  ├── vpc
 └── security
 ├── iam_role
 └── secret-manager
└── templates

環境に関連する構成

環境関連の構成とパラメーターを変数ファイルに分けて保持し、その値を渡してインフラストラクチャを構成します。例として

  • dev.backend.tfvar

      region = "ap-southeast-2"
      bucket = "dev-samplebackendterraform"
      key = "dev/state.tfstate"
      dynamo_db_lock = "dev-terraform-state-lock"
  • dev.variable.tfvar

    environment                     =   "dev"
    vpc_name                        =   "demo"
    vpc_cidr_block                  =   "10.20.0.0/19"
    private_subnet_1a_cidr_block    =   "10.20.0.0/21"
    private_subnet_1b_cidr_block    =   "10.20.8.0/21"
    public_subnet_1a_cidr_block     =   "10.20.16.0/21"
    public_subnet_1b_cidr_block     =   "10.20.24.0/21"

インフラストラクチャ部分の条件付きスキップ

env固有の変数ファイルに構成を作成し、その変数に基づいて、その部分を作成するかスキップするかを決定します。このようにして、必要に応じて、インフラストラクチャの特定の部分をスキップできます。

variable vpc_create {
   default = "true"
}

module "vpc" {
  source = "../modules/aws/network/vpc"
  enable = "${var.vpc_create}"
  vpc_cidr_block = "${var.vpc_cidr_block}"
  name = "${var.vpc_name}"
 }

 resource "aws_vpc" "vpc" {
    count                = "${var.enable == "true" ? 1 : 0}"
    cidr_block           = "${var.vpc_cidr_block}"
    enable_dns_support   = "true"
   enable_dns_hostnames = "true"
}

以下のコマンドは、各環境のインフラ変更を初期化して実行するために必要です。必要な環境フォルダーに移動します。

  terraform init -var-file=dev.variables.tfvar -backend-config=dev.backend.tfvar ../../deployment/

  terraform apply -var-file=dev.variables.tfvar ../../deployment

参考までに:https : //github.com/mattyait/devops_terraform


0

サブフォルダーの考え方は好きではありません。これは、環境ごとにソースが異なり、ドリフトする傾向があるためです。

より良いアプローチは、すべての環境(dev、preprod、prodなど)に単一のスタックを用意することです。単一の環境で作業するには、を使用しますterraform workspace

terraform workspace new dev

これにより、新しいワークスペースが作成されます。これには、専用の状態ファイルと、terraform.workspaceコードで使用できる変数が含まれます。

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${terraform.workspace}"
}

このようにして、バケットが呼び出されます

  • my-tf-test-bucket-dev
  • my-tf-test-bucket-preprod
  • my-tf-test-bucket-prod

上記のワークスペースに適用した後(terraform workspace select <WORKSPACE>環境を変更するために使用)。コードをマルチリージョンに対応させるには、次のようにします。

data "aws_region" "current" {}

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${data.aws_region.current.name}-${terraform.workspace}"
}

取得する(us-east-1リージョンの場合)

  • my-tf-test-bucket-us-east-1-dev
  • my-tf-test-bucket-us-east-1-preprod
  • my-tf-test-bucket-us-east-1-prod

0

従うべきいくつかのTerraformベストプラクティス:

  1. ハードコーディングを避ける:開発者が手動で直接リソースを作成する場合があります。これらのリソースをマークし、terraformインポートを使用してコードに含める必要があります。サンプル:

    account_number =“ 123456789012” account_alias = "mycompany"

  2. DockerコンテナーからTerraformを実行する:Terraformは、実行できるバージョンを簡単に制御できる公式のDockerコンテナーをリリースします。

CI / CDパイプラインでビルドジョブを設定するときは、Terraform Dockerコンテナーを実行することをお勧めします。

TERRAFORM_IMAGE=hashicorp/terraform:0.11.7
TERRAFORM_CMD="docker run -ti --rm -w /app -v ${HOME}/.aws:/root/.aws -v ${HOME}/.ssh:/root/.ssh -v `pwd`:/app $TERRAFORM_IMAGE"

詳細については、私のブログを参照してください:https : //medium.com/tech-darwinbox/how-darwinbox-manages-infrastructure-at-scale-with-terraform-371e2c5f04d3


0

このスレッドに貢献したいと思います。

  • Terraform Cloudを使用していない限り、これはAWS S3 + DynamoDBである可能性が最も高くなります。
  • 本番と非本番のバックエンドの個別のインフラストラクチャ(ネットワーク+ RBAC)。
  • 指定されたネットワーク(展開エージェントプールなど)の外部からの状態ファイル(ネットワークアクセスとRBAC)へのアクセスを無効にすることを計画します。
  • ランタイム環境でTerraformバックエンドインフラストラクチャを維持しないでください。別のアカウントを使用してください。
  • Terraformバックエンドでオブジェクトのバージョン管理を有効にして、変更と状態ファイルが失われないようにし、Terraformの状態履歴を維持します。

一部の特殊なケースでは、Terraform状態ファイルへの手動アクセスが必要になります。リファクタリング、変更の破棄、障害の修正などには、運用担当者がTerraform状態の操作を実行する必要があります。そのような場合は、要塞ホスト、VPNなどを使用して、Terraform状態への特別に制御されたアクセスを計画してください。

CI / CDパイプラインのガイドラインを含む詳細をカバーする、より長いベストプラクティスブログを確認してください。


-1

それでも優れたソリューションを探している場合は、ワークスペース固有の変数を持つことができるさまざまな環境のフォルダー構造を維持する代わりに使用できるワークスペースを見てください。

エフゲニー・ブリックマンとして 言及したことは、モジュール構造を持っている方が良いでしょう。


-1

上記のアドバイスとともに、Teraformクラウドを使用して状態を管理および保存します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.