「Terraform Backend用のリソースをService Catalogで管理したら便利かも」
個人的にはTerraform Cloudでstateファイルを管理する方法が好きですが、S3とDynamoDBを使用することがあると思います。
このリソースは、Terraform以外の方法で作成する必要があります。(stateファイルどこに置く問題が発生するため)
毎回手動でS3とDynamoDBを作るのは面倒なので、CloudFormation(以下CFn)テンプレート化してみました。 CFn化したことで楽にはなったんですが、組織内で楽に共有する方法はないかなと探していたらService Catalogを見つけました。
Service Catalogを使うことで、AWSのコンソール上からお手軽にTerraform state管理用のリソースをデプロイできます。
やってみた
ブログ中のコードは以下にあります。
msato0731/terraform-backend-cfn
CFnテンプレートの用意
state保管用のS3バケットと、排他制御用のDynamoDBを用意するCFnテンプレートです。
必要最低限のリソース定義になっています。
もっと細かく設定したい場合は、以下のリポジトリが参考になると思います。 (例えば、S3バケットの暗号化にSSE-KMSを使いたい等)
terraform-backend.yml
AWSTemplateFormatVersion: "2010-09-09"
Description: S3 & DynamoDB for Terraform Backend
Parameters:
Name:
Description: |
Name of the S3 bucket, DynamoDB table;
Defaults to "terraform-state-AWS_ACCOUNT_ID"
Default: ""
Type: String
Conditions:
GenerateNames: !Equals [!Ref Name, ""]
Resources:
#------------------------------------------------------------------------------#
# S3
#------------------------------------------------------------------------------#
StateBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
BucketName: !If
- GenerateNames
- !Sub "terraform-state-${AWS::AccountId}"
- !Ref Name
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
LifecycleConfiguration:
Rules:
- Id: ExpireOldVersions
NoncurrentVersionExpirationInDays: 90
Status: Enabled
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: "AES256"
#------------------------------------------------------------------------------#
# DynamoDB
#------------------------------------------------------------------------------#
LockTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Ref StateBucket
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
AttributeDefinitions:
- AttributeName: "LockID"
AttributeType: "S"
KeySchema:
- AttributeName: "LockID"
KeyType: "HASH"
Service Catalogで製品を登録
マネジメントコンソール
> Service Catalog
> 管理者
> 製品リスト
> 製品を作成
の順に選択します。
以下のように、必要な情報を入力します。
今回はGithubリポジトリにCFnのファイルを置いているので、CodeStarを使ってリポジトリと接続します。
ポートフォリオの作成
製品をプロビジョニングするために、ポートフォリオを作成します。
Service Catalog
の画面から管理者
> ポートフォリオ
> ポートフォリオの作成
の順に選択します。
以下のように情報を入力します。
ポートフォリオを作ったら、最初に作った製品を登録します。
最後にポートフォリオにアクセスできるように設定します。
今回はIAMロールにポートフォリオへのアクセス権限を付与しました。
製品をプロビジョニングする
準備が整ったので実際に製品をプロビジョニングして、Terraform State管理用のリソースを作成します。
Service Catalog
の画面からプロビジョニング
> 製品
> terraform-state-backend
> 製品を起動
の順に選択します。
リソースを作成できました。
補足
製品のバージョンアップ
外部リポジトリと接続している場合は、以下のように外部リポジトリ側で変更があるとバージョンが追加されます。
製品プロビジョニング時は、最新のバージョンがデフォルトで選択されます。
自動で追加されたバージョンには、製品バージョンが振られていません。
手動でバージョン情報をを設定することが可能です。 少し面倒ですが、運用上バージョン情報はあった方が良いため設定することをおすすめします。
CFnが使われているので、バージョンアップ前のリソースとバージョンアップ後のリソースで差分を確認することもできます。(変更セットみたいなイメージ)
組織内に共有する
Service Catalogのポートフォリオはアカウント間で共有もできます。
組織内の別アカウントで展開する場合は、ポートフォリオの設定を更新する必要があります。
詳細な手順は以下のブログがわかりやすいです。
おわりに
Terraformのstate管理用のリソースをService Catalogを使って作る手順でした。
組織のアカウントに共有しておけば、セルフサービス化が捗ると思いますので検討してもらえればと思います。
似たようなことはAWS Protonでもできますが、私としては単純にCFnをカタログ化したいだけならService Catalogの方が楽という感覚です。 (Protonでは、CFnをProton用にカスタマイズする必要があるため)
アカウント数が多くなるとこの方法でもstate管理のリソース自体の管理も大変になってくると思います。
その場合は、Terraform Cloudの利用を検討してみてください。
Terraform Cloud側でstateファイルを管理することが可能なので、今回のようにリソースを作る必要がありません。
ちなみに、stateファイルをTerraform Cloudに移すことはFreeプランでも試すことができます。
以上、AWS事業本部の佐藤(@chari7311)でした。