
Former2をローカルにホストして、既存リソースのCloudFormationテンプレートを出力してみた
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
最近以下の登壇資料を見てローカルでFormer2を使えると知り、「使ってみたい!」となったので実際にやってみたブログです。
Former2について解説されていて使ってみたいモチベが上がるので、Former2聞いたことない人やIaCよくわかんないよって人は是非読んでみて下さい。
Former2とは
既存のAWSのリソース情報を取得し、CloudFormation, Terraform, CDK等のテンプレート・コードを出力できるWebサービスです。
上記のサイトからそのまま利用できるのですが、AWSの認証情報(アクセスキー 、シークレットアクセスキー )を入力しなければいけないことから、セキュリティ上の不安がありました。
それが今回Dockerを使ってローカルでホストできるとのことで、これまでセキュリティ観点から利用できなかった方々は、この方法でFormer2を利用してみて下さい。
やってみた
Docker、Gitが利用できる前提で進めていきます。今回はローカルで起動したFormer2からReadOnlyAccessの権限をつけたロールを使用して、CloudFormationテンプレートを作成していきます。
Former2を起動
Former2は以下のリポジトリで公開されているので、コンテナ起動に必要なファイルをクローンします。
https://github.com/iann0036/former2
任意のフォルダで以下コマンドを実行します。
$ git clone https://github.com/iann0036/former2.git
クローンされたフォルダに移動し、コンテナを起動します。
$ cd former2 $ docker-compose up -d Creating former2_former2_1 ... done
あとはChromeなどのブラウザで127.0.0.1:80にアクセスしてみると、Former2の画面が確認できました。

IAMロールの作成
今回はIAMロールを使用するので、専用のロールを作成します。(既に利用できるロールがある/IAMユーザーを使用する場合は飛ばして構いません。)
IAMロール/ユーザーはAdministrator権限ではなく、なるべくReadOnlyAccessの権限を利用することをお勧めします。
利用したいAWSコンソールへログインしてIAM>ロールからロールの作成をしていきます。

アカウントIDはこのロールを引き受ける予定のアカウントを指定して下さい。

必要な権限ReadOnlyAccessを選択して進みます。

今回はFormer2というロール名で作成しました。

ロールを作成したので、このロールを使用してFormer2のCredentialsを設定していきます。
拡張機能の導入
ここからの手順、詳細については以下エントリで紹介されているので、細かい説明は省きます。結構重複する部分があるのは許してください。
setup>Introductionを開き、使用しているブラウザの拡張機能を追加します。

Former2 Helperをインストールできれば完了です。
認証情報の設定
IAMロールの権限で実行するために、Setup>Credentialsに入力する赤枠4項目を取得していきます。IAMユーザーで利用したい方はアクセスキー とシークレットアクセスキー を入力するだけで大丈夫です。

どうやってロールの認証情報を取得するかというと、以下のドキュメントに記載があります。
記載がある通りにターミナルから以下のコマンドを実行します。{AWS:AccountID}は作成したIAMロールのアカウントID、{IAM-user-name}にはロールを引き受けることができるIAMユーザーのプロファイルを指定してください。
$ aws sts assume-role --role-arn arn:aws:iam::{AWS:AccountID}:role/Former2 --role-session-name "RoleSession1" --profile {IAM-user-name} > assume-role-output.txt
assume-role-output.txtのファイルに必要な情報が出力されているので、コピー&ペーストでFormer2にそれぞれ入力しましょう。ここで取得できる認証情報のセッション時間はデフォルト1時間となっているので、Former2を利用する際に都度実行しましょう。
{
"Credentials": {
"AccessKeyId": "AAAAAAAAAAAAAAAAAAA",
"SecretAccessKey": "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
"SessionToken": "******************************************",
"Expiration": "2021-06-25T03:32:35+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AAAAAAAAAAAAAAAAAAA:RoleSession1",
"Arn": "arn:aws:sts::999999999999:assumed-role/Former2/RoleSession1"
}
}

その後のParameters、Settingsは全てデフォルトでOKです。
CloudFormationテンプレートを出力する
ここからは好きなリソースでテンプレートを出力するだけです。
今回は例として、Codeシリーズを使ったチュートリアルで作成したリソースがあったのでテンプレートにしてみます。このチュートリアルでは、CodeCommit,CodeDeploy,CodePipelineの3つのリソースを作成しました。
チュートリアル: シンプルなパイプラインを作成する (CodeCommit リポジトリ) - AWS CodePipeline
まずはCodeCommitをテンプレートにしてみます。Former2の使い方は簡単で、Dashboardを開くとAWSサービス一覧が表示されるので、利用したいサービスを選びます。

Credencialsで設定したAWSアカウントのリソースが表示されるので、チェックを入れてAdd Selectedをクリックすれば完了です。リソースが読み込み中のまま表示されない時は、右上のScan Againを実行しましょう。

画面上部にあるGenerateをクリックするとCloudFormationのテンプレートが作成されます。

これだけでも十分ありがたいのですが、Former2の凄いところは関連リソースを合わせて選択すると、組み込み関数の形でテンプレートが修正されるところです。
同じように、CodeDeployとCodePipelineもまとめてGenerateしたのが以下のテンプレートです。
AWSTemplateFormatVersion: "2010-09-09"
Metadata:
Generator: "former2"
Description: ""
Resources:
CodeCommitRepository:
Type: "AWS::CodeCommit::Repository"
Properties:
RepositoryDescription: "MyDemoRepo"
RepositoryName: "MyDemoRepo"
CodeDeployApplication:
Type: "AWS::CodeDeploy::Application"
Properties:
ApplicationName: "MyDemoApplication"
ComputePlatform: "Server"
CodeDeployDeploymentGroup:
Type: "AWS::CodeDeploy::DeploymentGroup"
Properties:
ApplicationName: !Ref CodeDeployApplication
DeploymentGroupName: "MyDemoDeploymentGroup"
DeploymentConfigName: "CodeDeployDefault.OneAtATime"
ServiceRoleArn: "arn:aws:iam::999999999999:role/CodeDeployRole"
AlarmConfiguration:
Enabled: false
IgnorePollAlarmFailure: false
DeploymentStyle:
DeploymentType: "IN_PLACE"
DeploymentOption: "WITH_TRAFFIC_CONTROL"
LoadBalancerInfo:
TargetGroupInfoList:
-
Name: "test-tg"
Ec2TagSet: {}
OnPremisesTagSet: {}
CodePipelinePipeline:
Type: "AWS::CodePipeline::Pipeline"
Properties:
Name: "MyFirstPipeline"
RoleArn: !Sub "arn:aws:iam::999999999999:role/service-role/AWSCodePipelineServiceRole-${AWS::Region}-MyFirstPipeline"
ArtifactStore:
Location: !Sub "codepipeline-${AWS::Region}-870438305283"
Type: "S3"
Stages:
-
Name: "Source"
Actions:
-
Name: "Source"
ActionTypeId:
Category: "Source"
Owner: "AWS"
Provider: "CodeCommit"
Version: "1"
Configuration:
BranchName: "master"
OutputArtifactFormat: "CODE_ZIP"
PollForSourceChanges: "false"
RepositoryName: !GetAtt CodeCommitRepository.Name
OutputArtifacts:
-
Name: "SourceArtifact"
Region: !Ref AWS::Region
Namespace: "SourceVariables"
RunOrder: 1
-
Name: "Deploy"
Actions:
-
Name: "Deploy"
ActionTypeId:
Category: "Deploy"
Owner: "AWS"
Provider: "CodeDeploy"
Version: "1"
Configuration:
ApplicationName: !Ref CodeDeployApplication
DeploymentGroupName: !Ref CodeDeployDeploymentGroup
InputArtifacts:
-
Name: "SourceArtifact"
Region: !Ref AWS::Region
Namespace: "DeployVariables"
RunOrder: 1
このように複数のリソースをまとめて出力することもできます。
AWS::CodePipeline::Pipelineが定義されているセクションを見ると、CodeCommitのリポジトリ名を指定するRepositoryNameは!GetAtt CodeCommitRepository.Nameと組み込み関数で取得してくれています。
同じくApplicationNameを定義する部分ではCodeDeployを!Ref CodeDeployApplicationの形で参照するように、自動でコードが生成してくれているのが最高ですね。
注意点
ここで作成されるテンプレートですが、そのままCloudFormationで流せるわけではありません。必須パラメータがなかったり一部コードに落とし込めていないなど、細かいエラーがあるので微調整は必要になります。
(今回の例ではCodeDeployDeploymentGroupのEc2TagSetやOnPremisesTagSetが不要なのに出力されてエラーになりました。)
盲信せずドキュメントの確認、作成したリソースが同じパラメータになっているかのチェックは忘れないようにしましょう。
まとめ
DockerでFormer2を起動できると聞いてウキウキで試してみました。触ったことのないサービスをコンソールから作成してコードの書き方を確認したり、検証環境で作成したリソースをコード化して本番環境の作成したりと幅広く利用できる超便利なツールです。
これまでセキュリティ観点から利用できなかった方々は、是非この方法でFormer2を利用してみてはいかがでしょうか?






