Help us understand the problem. What is going on with this article?

Serverless Framework利用時のアカウント毎のIAM権限について考えてみた

More than 3 years have passed since last update.

serverless frameworkを使って複数人で開発する場合のアカウント毎の権限について考えてみた。

やりたいこと

  • 参画ユーザ毎にアカウントを発行
  • 各アカウントでstage作成するための権限設定
  • 開発者の入場、退場に合わせた柔軟な運用

前提条件

  • 各アカウントとserverlessのステージ名を同一にしておく
  • 開発環境やステージング環境の設定は既に終わっているものとする

参画ユーザ毎にアカウントを発行

IAMの管理についてはmiamで良いかなと思っていたが、greeさんで作られているsubiamを使うことにした。

Subiamを使いAWSのIAM管理をコードベースでおこなう

以降はこのツール前提での話を進めていきます。

各アカウントでstage作成するための権限設定

stage作成にはcloudformationの作成やapigatewayの操作等、必要な権限が多いため非常に悩んだが、それぞれのAWSサービス毎に必要な権限を精査してみた。

cloudformationポリシーの作成

本番環境の設定を変更されては困るので、作成はできるが、変更、削除に制限を設けるようと、以下のようにした。
stack名はserverless側で設定されているs-resources.json などと暗黙的に合わせる。

policy "developer-cloudformation" do
  {
    Version: context.version,
    Statement: [
      {
        Effect: "Allow",
        Action: [
          "cloudformation:CreateStack",
          "cloudformation:DescribeStackResource",
          "cloudformation:DescribeStackResources",
          "cloudformation:DescribeStacks",
          "cloudformation:ListStacks"
        ],
        Resource: "*"
      },
      {
        Effect: "Allow",
        Action: [
          "cloudformation:DeleteStack",
          "cloudformation:UpdateStack"
        ],
        Resource: [
          "arn:aws:cloudformation:region:account-id:stack/project-name-dev-r/*",
          "arn:aws:cloudformation:region:account-id:stack/project-name-stg-r/*",
          "arn:aws:cloudformation:region:account-id:stack/project-name-${aws:username}-r/*"
        ]
      }
    ]
  }
end

apigatewayポリシーの作成

ステージ毎の更新の制限をかけたかったが、どうにも上手くいかず本番も変更できてしまう内容になっている。
現状では運用で回避している状態になってしまっている。

policy "developer-apigateway" do
  {
    Version: context.version,
    Statement: [
      {
        Effect: "Allow",
        Action: [
          "apigateway:GET"
        ],
        Resource: [
          "arn:aws:apigateway:region::/*"
        ]
      },
      {
        Effect: "Allow",
        Action: [
          "apigateway:PUT",
          "apigateway:POST",
          "apigateway:DELETE",
          "apigateway:PATCH",
          "apigateway:HEAD",
          "apigateway:OPTIONS"
        ],
        Resource: [
          "arn:aws:apigateway:region::/restapis/api-id/*"
        ]
      },
      {
        Effect: "Allow",
        Action: [
          "execute-api:Invoke"
        ],
        Resource: [
          "arn:aws:execute-api:region:*:api-id/${aws:username}/*",
          "arn:aws:execute-api:region:*:api-id/dev/*",
          "arn:aws:execute-api:region:*:api-id/stg/*"
        ]
      }
    ]
  }
end

lambdaポリシーの作成

エイリアス単位で上手くできれば良いのだが、こちらも自由に変更ができる権限になってしまっている。
deleteFunctionの権限は取り上げてしまってもよかったかもしれない。

policy "developer-lambda" do
  {
    Version: context.version,
    Statement: [
      {
        Effect: "Allow",
        Action: [
          "lambda:ListFunctions"
        ],
        Resource: "*"
      },
      {
        Effect: "Allow",
        Action: [
          "lambda:*"
        ],
        Resource: "arn:aws:lambda:region:account-id:function:project-name*"
      }
    ]
  }
end

iamポリシーの作成

ここで必要なことは

  • AWSマネージメントコンソールへのログイン
  • 自身のパスワード変更、MFA設定
  • lambdaへ割り当てるroleの作成、変更
  • lambdaへの特定のrole割当

こちらもserverless側とrole名などを暗黙的に合わせる必要がある

policy "developer-iam" do
  {
    Version: context.version,
    Statement: [
      {
        Effect: "Allow",
        Action: [
          "iam:ChangePassword",
          "iam:GetAccountPasswordPolicy",
          "iam:CreateVirtualMFADevice",
          "iam:DeactivateMFADevice",
          "iam:ListUsers",
          "iam:ListVirtualMFADevices",
          "iam:ListUserPolicies",
          "iam:DeleteVirtualMFADevice",
          "iam:GetLoginProfile",
          "iam:UpdateLoginProfile",
          "iam:EnableMFADevice",
          "iam:CreateLoginProfile"
        ],
        Resource: [
          "arn:aws:iam::account-id:user/",
          "arn:aws:iam::account-id:mfa/",
          "arn:aws:iam::account-id:user/${aws:username}",
          "arn:aws:iam::account-id:mfa/${aws:username}"
        ]
      },
      {
        Effect: "Allow",
        Action: "iam:PassRole",
        Resource: [
          "arn:aws:iam::account-id:role/project-name-dev-r-IamRoleLambda-xxxxxxxxxxxxx",
          "arn:aws:iam::account-id:role/project-name-stg-r-IamRoleLambda-yyyyyyyyyyyyy",
          "arn:aws:iam::account-id:role/project-name-${aws:username}-r-IamRoleLambda-*"
        ]
      },
      {
        Effect: "Allow",
        Action: [
          "iam:ListRoles",
          "iam:CreateRole",
          "iam:GetRole"
        ],
        Resource: [
          "*"
        ]
      },
      {
        Effect: "Allow",
        Action: [
          "iam:DeleteRole",
          "iam:DeleteRolePolicy",
          "iam:PutRolePolicy"
        ],
        Resource: [
          "arn:aws:iam::account-id:role/project-name-${aws:username}-r-IamRoleLambda-*"
        ]
      }
    ]
  }
end

これらの設定を併せ持つグループを作成する。

developer.rb

group "Developer", path: "/" do
  include_template "developer-apigateway", version: "2012-10-17"
  include_template "developer-iam", version: "2012-10-17"
  include_template "developer-lambda", version: "2012-10-17"
  include_template "developer-cloudformation", version: "2012-10-17"
end

ユーザの定義を行う
user.rb

user "quartette", path: "/" do
  login_profile password_reset_required: true

  groups(
    "Developer"
  )
end

こんな感じで、ユーザを増やしていけば何とかなるんじゃなかろうか。
実行は、

export AWS_ACCESS_KEY_ID='...'
export AWS_SECRET_ACCESS_KEY='...'
subiam -a --dry-run -f user.rb
subiam -a -f user.rb

開発者の入場、退場に合わせた柔軟な運用

正直まだいい案が無い状態。
PRのマージをトリガーとして、jenkinsで自動実行しているが、ユーザ作成時のクレデンシャルがだだ漏れになったりと、非常に穴のある状態。
このあたり良い運用方法などあればぜひ!

今回書いた内容はgithubでも公開しています。
github

Serverless Frameworkを利用した開発の進め方などについて今後も考えていきたいと思います。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away