2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LambdaをVPC内に作ってちょっとだけハッピーになった話

Last updated at Posted at 2019-12-23

前提

  • LambdaについてはServerlessFrameworkを使用
  • IP制限の掛かったサービスにWebhook的にLambdaから通知を送りたかった
    • SESのバウンス通知
    • 動画変換完了後の通知など(うちの会社ではよくあるパターン)

課題

  • これまではどうしていたかというと
    • IP制限の掛かっていないCloudFrontディストリビューションを作成
    • 上記のディストリビューションに対してドメインを振る(webhook.xx.com等)
    • アプリケーション側の該当のパス以下(/webhooks/hoge等)にベーシック認証を設定
    • Lambdaから上記のパスに通知

ペイン(辛み)

  • (ベーシック認証は掛けるものの)野ざらしになったWebhookディストリビューションを作ることになること
  • ドメインも別途発行する必要があること
    • クライアントによっては発行まで色々やり取り発生するし時間かかるしめんどくさい
    • 同時にSSLの設定等も増えるのでとにかくめんどくさい

解決策

  • 今回下記の流れで面倒くささが解消されました
    • LambdaをVPC内に作っちゃう
    • Lambdaを配置したPrivateサブネットに繋がったNATゲートウェイのIPをWAFに追加する
    • LambdaからメインのCloudFrontのURLを叩けるように書き換える

ゲイン(ハッピーになったこと)

  • IP制限を掛けている範囲内でアプリケーションが完結したこと
  • クライアントにドメインの追加申請をするという申し訳ない事態を防げたこと
  • VPC内にLambdaを作成するという新たな知見を得ることができたこと
  • 他にも同様の構成で悩んでいた人たちのちょっとした悩みを解消できたこと

解決策(解説)

LambdaをVPC内に作っちゃう

ServerlessFrameworkを使うとめちゃ簡単にできちゃいます。下記の通りserverless.ymlproviderに設置するサブネットとセキュリティグループを設定するだけ。

# serverless.yml
provider:
  name: aws
  runtime: ruby2.5
  region: ap-northeast-1
  stage: ${opt:stage, 'development'}
# 以下を追加
  vpc:
    securityGroupIds:
      - sg-xxxxxx
    subnetIds:
      - subnet-yyyyyy
      - subnet-zzzzzz

ちなみに私の場合は、複数の環境にまたいで管理をしているので実際はこんな感じで設定しています。

# serverless.yml
provider:
  name: aws
  runtime: ruby2.5
  region: ap-northeast-1
  stage: ${opt:stage, 'development'}
  vpc: ${self:custom.vpc.${self:provider.stage}}

custom:
  vpc: ${file(./vpc.yml)}
# vpc.yml
development:
  securityGroupIds:
    - sg-xxxxxx
  subnetIds:
    - subnet-yyyyyy
    - subnet-zzzzzz

staging:
  securityGroupIds:
    - sg-aaaaaa
  subnetIds:
    - subnet-bbbbbb
    - subnet-cccccc

production:
  securityGroupIds:
    - sg-dddddd
  subnetIds:
    - subnet-eeeeee
    - subnet-ffffff

微妙なハマリポイント

ちなみに一見、下記のようにVPC内でLambdaを実行するためのポリシーを設定しないとだめなように思いますが、むしろ下記を設定するとエラーが発生します。

# serverless.yml
provider:
  name: aws
  runtime: ruby2.5
  region: ap-northeast-1
  stage: ${opt:stage, 'development'}
  vpc:
    securityGroupIds:
      - sg-xxxxxx
    subnetIds:
      - subnet-yyyyyy
      - subnet-zzzzzz
# 下記を追加すると動かない
  iamManagedPolicies:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
  Serverless Error ---------------------------------------

  An error occurred: IamRoleLambdaExecution - Property ManagedPolicyArns contains duplicate values..

  Get Support --------------------------------------------

どうやらserverless.ymlvpcの設定を行ったことでServerlessFramework自身がよしなにAWSLambdaVPCAccessExecutionRole相当のポリシーを実行ロールに付与してくれるようで(実際に追加されてました)、「それと同じポリシーは追加できないよー」的な感じで怒っているようです。よしな力高いのは良いけど分かりづらいw

ということで、これによりLambdaをVPC内に作成することができました。あとはプロジェクトによって方針はまちまちだと思うので、うまい具合にやってもらえたらと思います。

以上、LambdaをVPC内に作ってハッピーになった話、でした。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?