Назад | Перейти на главную страницу

CloudFormation, сетевые проблемы с RDS и Lambda

Пытался получить Lambda с включенным HTTP для подключения к базе данных RDS, получения результатов и возврата к вызывающему. У меня всякие таймауты, и это сводит меня с ума. Я никогда особо не занимался инфраструктурой, поэтому кое-что из того, что я говорю, может быть упущено.

Когда я попытался создать базу данных Lambda и Postgres без каких-либо VPC, Lambda не подключилась к Postgres - там были тайм-ауты.

Когда я попытался создать базовый VPC и поместить в него Lambda и базу данных, Lambda подключилась и получила строки, но затем сама Lambda не могла выйти из VPC и истекло время ожидания.

Я пытаюсь сделать это через CloudFormation, поэтому мне не нужно особо беспокоиться о повторении своих шагов. Пока у меня есть это. Он должен создать

Я думаю, мне нужно как-то сделать эти группы для функций общедоступными, но я понятия не имею, как это работает. Может ли кто-нибудь направить меня на правильный путь?

ServerlessVPC:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock: "10.0.0.0/16"
ServerlessSubnetA:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::Subnet
  Properties:
    VpcId:
      Ref: ServerlessVPC
    AvailabilityZone: ${self:provider.region}a
    CidrBlock: "10.0.0.0/24"
ServerlessSubnetB:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::Subnet
  Properties:
    VpcId:
      Ref: ServerlessVPC
    AvailabilityZone: ${self:provider.region}b
    CidrBlock: "10.0.1.0/24"
ServerlessSubnetC:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::Subnet
  Properties:
    VpcId:
      Ref: ServerlessVPC
    AvailabilityZone: ${self:provider.region}c
    CidrBlock: "10.0.2.0/24"
ServerlessSecurityGroup:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: SecurityGroup for Serverless Functions
    VpcId:
      Ref: ServerlessVPC
ServerlessStorageSecurityGroup:
  DependsOn: ServerlessVPC
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: Ingress for RDS Instance
    VpcId:
      Ref: ServerlessVPC
    SecurityGroupIngress:
    - IpProtocol: tcp
      FromPort: '5432'
      ToPort: '5432'
      SourceSecurityGroupId:
        Ref: ServerlessSecurityGroup
    - IpProtocol: tcp
      FromPort: '11211'
      ToPort: '11211'
      SourceSecurityGroupId:
        Ref: ServerlessSecurityGroup
    SecurityGroupEgress:
ServerlessRDSSubnetGroup:
  Type: AWS::RDS::DBSubnetGroup
  Properties:
    DBSubnetGroupDescription: "RDS Subnet Group"
    SubnetIds:
    - Ref: ServerlessSubnetA
    - Ref: ServerlessSubnetB
    - Ref: ServerlessSubnetC
ServerlessRDSCluster: 
  DependsOn: ServerlessStorageSecurityGroup
  Type: "AWS::RDS::DBInstance"
  Properties: 
    DBName: ${self:custom.database_name}
    AllocatedStorage: 10
    DBInstanceClass: "db.t2.micro"
    Engine: "postgres"
    EngineVersion: "9.6.2"
    MasterUsername: ${self:custom.env.DATABASE_USER}
    MasterUserPassword: ${self:custom.env.DATABASE_PASSWORD}
    VPCSecurityGroups:
    - "Fn::GetAtt": ServerlessStorageSecurityGroup.GroupId
    DBSubnetGroupName:
      Ref: ServerlessRDSSubnetGroup
  DeletionPolicy: "Snapshot"    

Чтобы ваша функция Lambda (а) имела доступ к вашему экземпляру RDS и (b) доступ к внешнему миру, вам необходимо поместить свою функцию Lambda в свой VPC и добавить NAT к вашему VPC для доступа к внешнему миру.

Сделайте следующее:

  1. Поместите свою лямбда-функцию в частный подсеть в вашем VPC.
  2. Добавьте экземпляр NAT или шлюз в общественный подсеть.
  3. Убедитесь, что таблицы маршрутизации для вашей частной подсети разрешают доступ к экземпляру RDS.
  4. Убедитесь, что таблицы маршрутизации для вашей частной подсети направляют исходящий трафик на NAT.
  5. Если функции Lambda поддерживают группы безопасности, убедитесь, что группа безопасности вашего экземпляра RDS разрешает доступ к группе безопасности вашей функции Lambda. Если функции Lambda не поддерживают группы безопасности, убедитесь, что группа безопасности вашего экземпляра RDS разрешает доступ из вашей частной подсети или блока CIDR VPC.

Я не вижу общедоступных подсетей, шлюзов Интернета или NAT в вашем шаблоне облачной информации. Я не использую CloudFormation или Lambda, поэтому, возможно, в них есть какая-то магия, которая делает это ненужным, но для VPC в целом, если вы хотите, чтобы что-то в частной подсети могло общаться с внешним миром, вам нужен NAT. шлюз (желательно по одному на каждую зону доступности), общедоступную подсеть для шлюза NAT, Интернет-шлюз для шлюза NAT, через который можно разговаривать, и маршрут по умолчанию в ваших частных подсетях через шлюз NAT.

Если вы посмотрите на VPC по умолчанию в своей учетной записи и проследите все биты, которые он прикрепил, вы увидите структуру, которую вам нужно настроить.