Former2をローカルにホストして、既存リソースのCloudFormationテンプレートを出力してみた
最近以下の登壇資料を見てローカルで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を利用してみてはいかがでしょうか?