Terraform stateファイル管理用のリソース(S3,DynamoDB)作成のCFnをService Catalogに登録してみる
「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を使いたい等)
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)でした。