AWS Serverless Application Model

【AWS SAM】異なるアカウントへのデプロイ方法と躓きがちな落とし穴

ご挨拶

お疲れ様です、寺井です。

12月1日から無事に株式会社ディーネットの一員となることができました。
これからもここで力の限りアウトプットし続けていこうと思います!

早速ですが、今回やることは前回の記事(【AWS SAM】SAM CLIを使って今流行りのIaC環境を構築してみた)の続編で、SAM CLIで異なるアカウントにデプロイする手順や、SAMを使うにあたって私が引っかかったSAMの落とし穴についてまとめていきたいと思います。

今回のゴール

SAM CLIを使用して開発環境のAWSアカウントから、本番環境である別のAWSアカウントにデプロイできるようにする。

実施すること

おおまかな手順は以下の通りです。

  1. IAMロール(信頼ポリシー)の作成
  2. EC2認証情報(credentials)の設定
  3. SAM CLIでデプロイ

今回はIAM ユーザーアクセスキーは使用せず、AssumeRoleでIAMロール権限の受け渡しを行います。

準備

前回の記事の内容を元に、SAM CLI環境があって、「Hello world」テンプレートも用意済みである、という前提で話を進めていきます。

SAMで異なるアカウントにデプロイするので、AWSアカウントが2つ必要になります。
今回は便宜上以下のように定義します。

  • 本番アカウント:987654321098
  • 開発アカウント:123456789012

実装

IAMロールの作成(本番アカウント)

まずは本番環境にて、開発アカウントが引き受けることを許可するIAMロールを作成します。

IAM > ロール > ロールを作成

今回設定するポリシーは前回と同じく以下の通りです。

こちらで作成したIAMロールのARNを後ほど使用するためコピーしておいてください。
(arn:aws:iam::{アカウントID}:role/{IAMロール名})

IAMロールに信頼されたエンティティを設定(本番アカウント)

IAM > ロール > {先ほど作成したロール名} > 信頼ポリシーを編集

先ほど作成したIAMロールの[信頼関係]タブを選択

[Principal]の[AWS]欄に開発環境のEC2に付与しているIAMロールのARNを入力

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::123456789012:role/{開発環境のEC2に付与しているIAMロール名}"
                ]
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

これで開発環境からAssumeRoleして利用できる、本番環境へのデプロイ用のIAMロールができました。

EC2認証情報の設定(開発環境)

まず「credentials」ファイルを作成するために、「aws configure」コマンドで初期設定を行います。

# 現在の認証情報を確認
$ aws configure list

# 出力内容(EC2に付与されているIAMロール情報が出力されている)
~~~~~
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************abcd         iam-role
secret_key     ****************efgh         iam-role
    region                <not set>             None    None
~~~~~
# AWS CLI初期設定を行う
$ aws configure

# 入力内容(AWSアクセスキーは使用しないため、適当な文字を入力して進めていきます。)
~~~~~
AWS Access Key ID [None]: hoge
AWS Secret Access Key [None]: hogehoge
Default region name [None]: ap-northeast-1
Default output format [None]:
~~~~~

ec2-userのホームディレクトリ直下に「.aws」という隠しフォルダが生成された

~~~~~
/home/ec2-user/.aws/
├ config
└ credentials
~~~~~

EC2の[credentials]を編集(開発環境)

作成時にコピーした、本番環境で作成したIAMロールのARNを使用します。

$ vim .aws/credentials

# 編集前
~~~~~
[default]
aws_access_key_id = hoge
aws_secret_access_key = hogehoge
~~~~~

# 追記
~~~~~
[{任意のプロファイル名}]
role_arn = arn:aws:iam::123456789012:role/{ロール名}
credential_source=Ec2InstanceMetadata
~~~~~
  • プロファイルを指定しなければ[default]の認証情報が適用される
  • 追記したプロファイル名を指定すれば[本番環境のIAMロール]を使用した認証情報が適用される

(補足:CLI初期設定でアクセスキーを設定していなければ、EC2に付与されているIAMロールの権限で実行されます。)

実際に本番環境へデプロイ(開発環境)

これにて基本的な設定は完了したため、実際にデプロイしてみましょう。
(補足:「-g」オプションをつけて、デプロイに必要な設定を行う)

$ sam deploy -g --profile {作成したプロファイル名}

~~~~~
Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-app]: sam-app(任意の名前)
        AWS Region [ap-northeast-1]:
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]:
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]:
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]:
        HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]:
        SAM configuration file [samconfig.toml]:
        SAM configuration environment [default]:

~
~
~
Successfully created/updated stack - sam-app in ap-northeast-1

~~~~~

本番環境アカウントのマネジメントコンソールから、CloudFormationを見てみると、デプロイされていることが確認できるかと思います。

落とし穴

IAMポリシー(AssumeRole)

一番悩まされました・・・。

今回は異なるアカウントへのデプロイを行う際の権限設定を、AWSアクセスキーを使用せずIAMロールによる設定を行いました。
AWSアクセスキーなら、対象のユーザーのアクセスキーを埋め込めば済むんですが、IAMロールはそう簡単にいきません。

「これはどっちのアカウントで設定するのか」「今このアクションではどっちのIAMロールが使用されているのか」等、完全に迷子になりました。

今回のケースで必要な項目をまとめるとこんな感じ

  • [開発環境] 開発を行うEC2に、本番環境のIAMロールを受け入れるIAMロールを付与する。

    • 必要なIAMポリシー
      {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Effect": "Allow",
              "Action": "sts:AssumeRole",
              "Resource": "arn:aws:iam::987654321098:role/{開発環境のEC2に付与しているIAMロール名}"
          }
      ]
      }
  • [本番環境] 「信頼されたエンティティ(Principal)」に開発アカウントのEC2に設定したIAMロールを指定したIAMロールを作成する。

    • 必要なIAMポリシー:SAM(CFn)によって作成されるリソースの作成権限

簡単にまとめると、開発環境から本番環境へデプロイするとき、その都度本番環境のIAMロールを借りて実行するということになります。

SAM テンプレートのPackageTypeはこだわりがなければ[zip]で

[Image]にすると、Amazon ECRにImageファイルが格納されることになって確認し辛い。
[zip]なら皆大好きS3に保存されるので扱いやすい。

SAM CLIを使うなら最後までSAM CLIを使う

CloudFormationでリソースが作成されたあとから、追加で一部のリソースを手動で作成したりすると、権限が足りなかったり、スタックを変更する度に結局追加作業が必要だったりと、SAMを使用しているメリットが薄れてしまいます

必要なリソースについては、基本的にSAMテンプレート内で全て扱うようにしましょう。

感想

「SAM CLI」は使いこなすことが出来れば素晴らしいツールですが、そのための学習コストは結構必要になるなと感じました。

しかしながら、開発効率・管理が容易になる等、メリットは絶大なものになると思うので、少しずつでも学習してスキルを積み重ねていきたいですね。
まだまだ未熟者なので、「こうした方がもっとええで」「それはちゃうやろ」などお気づきの点があれば気軽に教えてください!

お疲れ様でした。

<参考サイト>
AWS CLI でのIAMロールの使用 - AWS Command Line Interface
sam deploy オプション一覧 - AWS Serverless Application Model

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA