AWS documentDBにLambdaから書き込むメモ(terraform)

目的

  • documentDBにLambdaから書き込みたい
  • 構成はterraformにて行う

LambdaのVPC接続について

VPC接続

  • LambdaはVPC接続して動かすという方法がある模様
    • LambdaがVPC(自分で作ったVPC)にアクセスして動作するイメージ

利点

  • VPC内のエンドポイント等にLamdaからアクセスできる
  • VPC内のリソースにLamdaがアクセスする際、Security Groupによるアクセス制御が可能(これが非常に嬉しい)

昔は遅かった

  • VPC内接続のLambdaは昔は非常に遅く、一回の実行10秒とかかかってたらしい(ENIをまいどまいど作っていた)

DocumentDBへのLamdaからのアクセス(VPC接続)

  • DocumentDBはパブリックなエンドポイントを持たない
    • VPCのリソースからのアクセスしかできない(もしくはLB等でのアクセス)
  • LambdaをVPCに接続して、DocumentDBへアクセスさせる

DocumentDBへのLamdaからのアクセス(VPC接続しない場合)

  • LBを使ったアクセス方法もあるらしい(ちょっと古い記事だけど)

dev.classmethod.jp

DocumentDBを作る

  • docdb.tf
resource "aws_docdb_subnet_group" "service" {
  name       = "docdb-${var.base_name}-subnet"
  subnet_ids = [var.subnet_for_docdb1.id, var.subnet_for_docdb2.id]
}

resource "aws_docdb_cluster_instance" "service" {
  count              = 1
  identifier         = format("docdb-%s-instnace-%02d", var.base_name, count.index + 1)
  cluster_identifier = aws_docdb_cluster.service.id
  instance_class     = var.docdb_instance_class
}

resource "aws_docdb_cluster" "service" {
  skip_final_snapshot             = true
  db_subnet_group_name            = aws_docdb_subnet_group.service.name
  cluster_identifier              = "docdb-cluster-${var.base_name}"
  engine                          = "docdb"
  master_username                 = var.docdb_admin_user
  master_password                 = var.docdb_password
  db_cluster_parameter_group_name = aws_docdb_cluster_parameter_group.service.name
  vpc_security_group_ids          = [aws_security_group.docdb.id]
}

resource "aws_docdb_cluster_parameter_group" "service" {
  family = "docdb3.6"
  name   = "docdb-parameter-group-${var.base_name}"
}
  • variable.tf
# name
variable "base_name" {}

# vpc information.
variable "vpc_main" {}

# subnet for docdb
variable "subnet_for_docdb1" {}
variable "subnet_for_docdb2" {}

# instance class
variable "docdb_instance_class" {
  default = "db.t3.medium"
}

# admin
variable "docdb_admin_user" {}
variable "docdb_password" {}

# allowd security group
variable "allowed_security_group" {}
  • security-group.tf
resource "aws_security_group" "docdb" {
  name   = "docudb-${var.base_name}"
  vpc_id = var.vpc_main.id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group_rule" "allowd_secutiry" {
  type                     = "ingress"
  from_port                = 0
  to_port                  = 0
  protocol                 = "-1"
  source_security_group_id = var.allowed_security_group.id
  security_group_id        = aws_security_group.docdb.id
}

ポイント

  • security groupを指定している
resource "aws_docdb_cluster" "service" {
  ...
  vpc_security_group_ids          = [aws_security_group.docdb.id]
}
  • このaws_security_group.docdbにて特定のsecurity groupからしかアクセスを許可しない設定にしている(これがLambdaのsecurity group)
resource "aws_security_group_rule" "allowd_secutiry" {
  ...
  source_security_group_id = var.allowed_security_group.id
}

Lambdaを作る

  • lambda.tf
resource "aws_lambda_function" "lambda" {
  ...
  vpc_config {
    subnet_ids = [
      var.subnet_for_lambda1.id,
      var.subnet_for_lambda2.id
    ]
    security_group_ids = [aws_security_group.for_lambda.id]
  }

  environment {
    variables = {
      DOCDB_CLUSTER_ENDPOINT = var.docdb_cluster_endpoint
      DOCDB_ADMIN_USER       = var.docdb_admin_user
      DOCDB_ADMIN_PASSWORD   = var.docdb_password
    }
  }
}

このようにvpc_configをつけてやればVPC接続で動いてくれるらしい

Lambdaのロールについて

  • VPC接続で実行する場合、ENIを作ったり、アクセスしたりするので、そのあたりの権限が必要
    • このあたりが必要らしい参考
ec2:CreateNetworkInterface
ec2:DescribeNetworkInterfaces
ec2:DeleteNetworkInterface
  • AWSLambdaVPCAccessExecutionRoleこれを使えばいいとか。

github.com

Lambdaソース

  • 公式を参考に

プログラムによる Amazon DocumentDB への接続 - Amazon DocumentDB

実行

X-rayで見てみました

  • 初回起動時(コールドスタート)

    • 結構遅い f:id:y-ni-shi:20200830001810j:plain
  • 2回め起動時

    • 1回目よりは速い(しかし全体で400ms.遅い) f:id:y-ni-shi:20200830001814j:plain
  • メモリを大きくしてもそこまで速度変わらず

まとめ

  • DocumentDBはパブリックなエンドポイントを持たないので、Lambdaからアクセスするには工夫が必要
    • LambdaをVPCアクセス
    • LambdaからLBでアクセス
  • LambdaのVPC接続は昔は遅かったけど、今は速い
    • ENIにアクセスするコストはかかっていると思われるが、大したこと無い
  • documentDBへのアクセスはほどほどに時間かかりそう(単なる通信のコストだろうか)
  • VPC接続なしのdocumentDBアクセスでどれくらいの速度かやってみたい(LBでのアクセス)