はじめに
re:Invent初参加!上司と先輩に囲まれて5人で行ってまいりました。
自己紹介:普段は主にC#を書いてWEBアプリケーション開発(バックエンド、フロントエンド)をしています。AWS歴は1年ちょいで、基本的なサービスは触ったことがありますが、IaCはまだ「なんとな~くわかる(わからない)」レベルでした。つまり初心者です。
現在のプロジェクトではマルチテナントSaaS基盤を開発しており、「テナントごとの環境を自動でプロビジョニングする仕組み」をIaCで自動化する予定があります。Step Functions × CloudFormation StackSetsで一気通貫、という設計があったものの、なかなか着手できていない状態です。
そこで今回、IaC(Infrastructure as Code)をテーマに徹底的にワークショップを回ると決めました。キーノートもほどほどにひたすらハンズオン。結果、9本のワークショップに参加し、そのうち特にIaC手法がメインだった3本(CDK・Terraform・CloudFormation)をプロジェクトへの活かし方とともに振り返ります。
(おまけとしてラスベガスに行く際の初心者向けTipsも!あんまりネットで見つけられなかった情報なのでもうこれがメインかも。)
プロジェクトの背景(ざっくり)
参加前の状況:
- マルチテナント型のSaaS基盤(詳細は伏せますが、複数のAWSサービスを組み合わせた構成)
- テナントごとに独立した環境をプロビジョニング
- テナント毎の設定により、構成やリソース量を変える
- 余裕があれば他の環境構築(テナント共通基盤)や、半自動化されてはいるものの手動作業が残るAPIGatewayのデプロイ、Jenkinsからの移行を考えているCI/CDパイプラインなど、IaCでの自動化のヒントがつかめたら……
アプリ側の機能改修に追われ、とりあえずコンソールでぽちぽち作成……改善するべきなのは自明ですが、なかなか踏み出せませんでした。
1. 【CDK】DVT305:Develop AWS CDK resources to deploy your applications on AWS (AWS にアプリケーションをデプロイするための AWS CDK リソースを開発する)
公式ワークショップ:AWS CDK Workshop
CDKでAPI Gateway + Lambda + DynamoDBを組み合わせた「Hit Counter」アプリを作って、それをConstructという再利用可能なコンポーネントにするワークショップ。最後にJestでテストも書く流れでした。
Constructの強力なコンセプト
CDKの一番の特徴は**Construct(コンストラクト)**という概念。複数のAWSリソースを1つのコンポーネントにバンドルして、誰でも再利用できるようにする仕組みです。
ワークショップでは、Lambda + DynamoDB + IAMロールという「URLヒットカウンター」の機能を、HitCounterという1つのConstructにまとめました。
// 使う側はこれだけ
const hitCounter = new HitCounter(this, 'MyHitCounter', {
downstream: helloFunction
});
たった3行で、内部的に下記を全部作ってくれます。
- DynamoDBテーブル(暗号化設定込み)
- Lambda関数(環境変数設定済み)
- IAMロール(必要最小限の権限)
- Lambda関数とDynamoDB間の権限設定
これを毎回あれこれ書いてたら大変ですが、Constructにまとめることで「Hit Counterという概念」として扱える。責務が明確になって、他のプロジェクトでも再利用できる。
普段C#書いてオブジェクト指向でやっているのでこれはとても取っつきやすいです。(コード上でもそのままですが)クラスですからね。
さらに、Construct Hub(https://constructs.dev)にはコミュニティが作った再利用可能なConstructが大量にあって、npm installするだけで使えます。ワークショップでもcdk-dynamo-table-viewerをインストールして、DynamoDBの内容を表示するエンドポイントを1行で追加しました。
CloudFormationだと同じリソースを毎回YAMLで書く必要がありますが、CDKならコンポーネントとして切り出せるのが強みですね。
便利ポイント:grant系メソッド
最初にLambdaとDynamoDBを作ってデプロイしたら502エラー。CloudWatch Logsを見ると「DynamoDB への書き込み権限がない」というAccessDenied。そこでtable.grantReadWriteData(this.handler)を1行追加したら、IAMポリシーが自動生成されて動きました。
次は下流のLambda呼び出しでまたAccessDenied。props.downstream.grantInvoke(this.handler)を追加してまた解決。
わざわざIAMポリシーをJSONで書く必要がなく、メソッド1つで必要最小限の権限を自動生成してくれるのが便利だなと。cdk diffで事前に実際のjsonのIAMポリシーの変更内容が確認できるのがいいですね。
インフラのテストが書ける
インフラでテスト?とピンと来なかったのですが、オプションでCDK Constructのテストを書く流れがあって、普段の開発と変わらないことを実感できました。
test("DynamoDB Table Created", () => {
const stack = new Stack();
new HitCounter(stack, "MyTestConstruct", { downstream: testLambda });
const template = Template.fromStack(stack);
template.resourceCountIs("AWS::DynamoDB::Table", 1);
});
アプリのユニットテストと同じ感覚でTDDサイクルがインフラでも回せます。DynamoDBテーブルに暗号化を追加する要件が来た想定で、先にテストを書いて失敗させて、実装を追加してパスさせる流れを体験しました。
C#でも書ける
ワークショップはTypeScriptかPythonを選ぶ形式でしたが、AWS CDKは他の言語もサポートされてます。プロジェクトがC#メインなので、インフラもC#で統一するのがいいのかなと。
(TypeScript未経験なんですが、なんとなくコードの意味は分かりました。MicroSoft言語、ありがとう)
本当はC#で実装するところまで行きたかったんですが、間に合いませんでした……。
プロジェクトへの適用
HitCounterの考え方を応用して、テナント環境作成のコンストラクトを作るイメージが湧きました。テナントごとに必要なリソースをひとまとめにしておき、ユーザーの操作からCDKデプロイを実行する。AWSコンソールをポチポチせずに済みます。しかもC#だから開発メンバー全員読めるのがありがたいですね。
2. 【Terraform】CNS312-R1:Building Serverless applications with Terraform workshop(Terraform を使用したサーバーレス アプリケーションの構築ワークショップ)
公式ワークショップ:AWS Terraform Workshop
「グリーティングカード生成アプリ」をTerraformで段階的に構築するワークショップ。S3に猫の写真をアップロード→Lambda で処理→HTMLカードを生成、という流れを、最初はシンプルに作って、徐々にSQSやAPI Gatewayを追加していく形式でした。

Terraformモジュールで再利用性を高める
リソースをmodules/lambda、modules/sqs、modules/api_gatewayのように分割して、main.tfから呼び出す設計。
CDKのConstructと似た考え方ですね。モジュールにしておけば、他のプロジェクトでも使い回せるし、パラメータを変えるだけで別の環境にも対応できる。
便利だったのが、terraform graphコマンドで依存関係を自分で可視化できること。
terraform graph | dot -Tpng -o module-dependency.png
これだけで、モジュール間の依存関係が図として出力されます。複雑な構成になったときに「どの順番でリソースが作られるのか」が一目瞭然になるので、かなり重宝する機能だなと。
Checkovでポリシー違反を自動検出
Checkovというオープンソースのツールで、インフラコードがポリシーに準拠しているかをチェック。
例ではこんなルール:
- Lambdaのメモリが2048MBを超えていないか(コスト管理)
- X-Rayトレーシングが有効か(可観測性)
- 承認されたランタイムだけ使っているか(セキュリティ)
これをpre-commitフックに組み込むと、ローカルでコミットする前に自動チェックしてくれます。「ポリシー違反のコードは絶対にプッシュできない」仕組み。
こういうルール強制システムがあることで、このルールが完全に守られていることを証明できる(=エビデンスとなる)のもいいですね。
イベント駆動型CI/CDパイプライン
ワークショップのボーナスステージは、Terraform自身で作るCI/CDパイプライン。
(ここまでは間に合いませんでした……)
-
git pushでコードをS3にプッシュ(Gitリモートとして使う) - S3のイベントをEventBridgeが検知
- EventBridgeがCodeBuildをトリガー
- CodeBuild内でCheckovチェック→パス→
terraform apply
ポリシー違反があったらデプロイが止まる。全部AWSマネージドサービスなのでサーバーレスで、コスト効率・IAMなど権限が最小限となり安全性も高い。あと完全な監査証跡が得られるというのが地味に大きいなと。
やや理解できていない部分も多いので、今後試して知識にしていきたいです。
プロジェクトへの適用
Terraformモジュールでテナント固有リソースを管理して、variables.tfでテナント設定の差分を吸収する、とか。
Checkovのポリシーチェックや監査証跡など、例えそのままCI/CDパイプラインに組み込めずとも、必要な概念として勉強になりました。
3. 【CloudFormation】DVT304:Deploy infrastructure with speed and safety using AWS CloudFormation(AWS CloudFormation を使用して迅速かつ安全にインフラストラクチャをデプロイする)
公式ワークショップ:(まだ公開されていない模様)
シンプルな静的ウェブサイト(S3 + CloudFront)を、モニタリング(CloudWatch Alarms)、ロギング、セキュリティ(WAF)を追加して本番対応にしていくワークショップ。「デプロイする前にエラーを捕まえる」をテーマに、VS Code + AWS Toolkit + Amazon Q Developerを使った開発フローを体験しました。
IDE内で完結する早期検証
CloudFormationテンプレートを編集していると、VS CodeにインストールしたAWS Toolkitに統合されているcfn-lintがリアルタイムで構文チェックしてくれます。CloudWatchアラームを追加する際、EvaluationPeriod(単数形)と書いてしまったところ、エディタ上に即座に赤線が表示されて「EvaluationPeriods(複数形)じゃないとダメ」と教えてくれました。
さらにCloudFormation Guardで、セキュリティポリシー違反もチェックできます。S3バケットの暗号化が無効、バージョニング無効、パブリックアクセス許可、といったコピペ流用で陥りがちな罠を自動検出してくれました。
動的ネーミングでマルチテナント対応
プロジェクトに使えそうだなと思ったのは、疑似パラメータによる動的ネーミング。当たり前ですがS3バケット名をハードコーディング(my-bucket-nameみたいに固定)すると、ユニークではないので2つ目のテナント環境で必ず失敗します。
そこで${AWS::StackName}や${AWS::AccountId}を使ってバケット名を動的生成すると、1つのテンプレートで複数テナントに対応できます。
BucketName: !Sub '${AWS::StackName}-logs-${AWS::AccountId}'
さらに**Change Sets(変更セット)**で、デプロイ前に「どのリソースが追加・変更・削除されるか」をプレビューできます。手動変更とテンプレートの差分(ドリフト)を検出してくれるのが一番ありがたいですね。(ありがち罠)
動的参照で柔軟なテンプレート
パート3では、リソース間の参照を**!Refと!GetAtt**で動的にする重要性を学びました。ARNをハードコーディングすると、別環境に持っていけない&リソース名変更で壊れます。
# ダメな例
LogDestinationConfigs:
- 'arn:aws:s3:::my-hardcoded-bucket-name'
# 良い例
LogDestinationConfigs:
- !GetAtt WAFLoggingBucket.Arn
これで、バケット名を変えても自動で追従してくれる上、CloudFormationが依存関係を理解して正しい順序でリソースを作ってくれます(暗黙的依存関係)。
Amazon Q Developerの活用
エラー箇所で右クリック→「Explain with Q」でエラー内容の解説、「Fix with Q」で修正案を提示してくれます。使ってみた感想としては、正直「他のAIでもできそう?」と思う部分もありました。ただ、AWS特有のセキュリティポリシー違反やcfn-guardと連携した検出は、やっぱり専用ツールの方が強いのかなと感じました。
プロジェクトへの適用
疑似パラメータによる動的ネーミング、リソース間の動的参照は、そのまま各テナント環境のテンプレートに使えるなと。
Change Setsをデプロイ前に確認するフローや、ポリシーチェックを強制する仕組みなんかもCI/CDに組み込めるかもしれません。
まとめ
IaCで共通する重要な構造
CDK、Terraform、CloudFormationと3つの手法を体験して気づいたのは、ツールは違えど、大切にすべき構造や原則は取り入れられるはずということ。
-
コンポーネント化(Construct / Module)
複数リソースを再利用可能な単位にまとめる -
ポリシーの外出し(Policy as Code)
ガバナンスルールをコードとして定義し、強制する -
動的な参照・ネーミング(Pseudo Parameters / !Ref / !GetAtt)
環境ごとの差分を吸収し、再利用性を高める -
変更の可視化(Change Sets / terraform plan)
デプロイ前に影響範囲を確認し、ドリフトを検出 -
最小権限の原則(grant系メソッド / IAMポリシー)
必要最小限の権限を自動生成 -
テスト(Jest / TDD)
インフラもコードなので、当然テストを書く
手法は何であれ、こういう構造を意識して作ることが、保守しやすく安全なインフラにつながるのだと思います。
プロジェクトに活かす
CDK、Terraform、cloudformation……いろいろな手法のIaCを体験しましたが、個人的にはCDKが一番プロジェクトに合っているかなと感じています。
プロジェクトのメンバーがインフラというよりは開発者メインというのもあり、メンバー皆が理解できるものを基盤にできるというのが強いかなと。みんなC#大好きオブジェクト指向大好き(なはず)なので……。
時間を見つけてTenantInfraConstruct(適当に命名)のプロトタイプを作っていこうと思います。
IaCワークショップ漬けにして良かったこと
セッションも面白そうでしたが、ハンズオンで実際に手を動かしたことで、「これならできそう」という感覚を掴めました。普段触っているECSやAPIGatewayなんかはIaCになっても取っつきやすかったですね。ただ普段全然触ったことのないものは理解が追いつかないものも多く、コードをコピペしただけで、なんかよくわかってないけどなんか動いているな……という状況になってしまうので復習が大切だなとは実感しました。
一番はAWSのプロフェッショナル達に質問しながら進められることですね!
反省
事前に予約したワークショップでいっぱいいっぱいで、新サービスの追加セッションに参加できなかったことです。
あと万年インドア派(基本家から一歩も出ないで生活します)で単純に体力がなさ過ぎるのにはしゃぎすぎてしまい、疲労が溜まって帰国してから完全に体調を崩しました。
おまけ:初参加(海外初心者)向けのTips
よくネット上の情報に記載されていること以外でこれ必要や!と思ったもののまとめです。
準備編
- Uberは日本でいれておけ - 現地で登録しようとすると電話番号の承認で詰むことがあります。
- OpenTableも日本でいれておけ - レストランの予約はOpenTableが多く、これも現地で登録しようとすると電話番号の承認で詰むことがあります。
- yelpも日本でいれておけ - たまにOpenTableではなくyelpの場合もあります。
- インスタント味噌汁と割りばしをもっていけ - 数日で故郷の味が欲しくなります。切実に。
- 携帯湯沸かし器があるとなおよい - 同室の先輩が持ってきていて本当にありがたい気持ちになりました。(ホテルでお湯を入手するにはチップで人に頼むくらいしかできません。)
現地編
- 清掃は毎日電話か直接頼もう - ホテルによりけりだと思うのですが、なぜか全然清掃がされず、毎回フロントに頼みにいってました。毎日清掃してください、と伝えても翌日も翌々日もされない……。最終的に毎朝電話で頼むか、廊下にいる清掃係の方に直接お願いするしかないと学びました……。
- 洗濯は確かにできるが大変 - 滞在日数が長かったので日数分の衣類ではなく洗剤・洗濯用の袋・物干し用の紐を持っていきました。確かにできるし乾燥しているのですぐ乾くのですが、普通に疲れて帰ってきてから手洗いするのは結構大変です。(ただホテルのランドリーサービスはかなり高く、コインランドリーも近所にはないのでなかなか難しいところ。)
セッション編
- 時間内には終わらない - 私が1年ちょいというAWS初心者なのもありますが、普通に2時間では終わらないボリュームのセッションも多いです。ワークショップの環境自体は4時間開いているので、その後の時間で続きをやるか、自分がやりたい部分だけやる、など工夫が必要です。
- 資料は保存しておこう - 数日~数週間で公開されるワークショップもありますが、なかなか公開されないワークショップもあります。PDF化してNotebookLMに突っ込みましょう。
拙いレポートですが、お読みいただきありがとうございました!

