代码之家  ›  专栏  ›  技术社区  ›  Alexandru Romînu

专有网络中的Terraform Lambda允许HTTP请求的网络访问

  •  0
  • Alexandru Romînu  · 技术社区  · 2 年前

    我第一次使用Terraform,在配置中有点迷失了方向,我的Lambda函数也面临这个问题,它应该能够对google.com或swapi.com(或任何其他外部API)进行简单的HTTP请求。 在我的linkedin回调中,我需要使用linkedin api。 以下是我的一些配置:

    terraform {
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = ">= 5.21.0"
        }
    
        random = {
          source  = "hashicorp/random"
          version = ">= 3.3.0"
        }
    
        archive = {
          source  = "hashicorp/archive"
          version = ">= 2.2.0"
        }
      }
    
      required_version = ">= 1.0"
    }
    
    
    provider "aws" {
      region     = var.region
      access_key = var.access_key
      secret_key = var.secret_key
    }
    
    resource "aws_vpc" "main_vpc" {
      cidr_block           = "10.0.0.0/16"
      enable_dns_support   = true
      enable_dns_hostnames = true
    
      tags = {
        Name = "main-vpc"
      }
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_internet_gateway" "main_igw" {
      vpc_id = aws_vpc.main_vpc.id
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_route_table" "route-table-main" {
      vpc_id = aws_vpc.main_vpc.id
      route {
        cidr_block = "0.0.0.0/0"
        gateway_id = aws_internet_gateway.main_igw.id
      }
    
      tags = {
        Name = "main-route-table"
      }
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_eip" "nat_eip" {
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_nat_gateway" "nat_gateway" {
      allocation_id = aws_eip.nat_eip.id
      subnet_id     = aws_subnet.main_subnet_nat_gateway_a.id
    
      tags = {
        Name = "nat-gateway"
      }
    }
    
    resource "aws_route_table" "route-table-nat" {
      vpc_id = aws_vpc.main_vpc.id
      route {
        cidr_block = "0.0.0.0/0"
        gateway_id = aws_nat_gateway.nat_gateway.id
      }
    
      tags = {
        Name = "nat-route-table"
      }
    }
    
    resource "aws_security_group" "main_sg" {
      name        = "main-sg"
      description = "Terraform SG"
      vpc_id      = aws_vpc.main_vpc.id
    
      ingress {
        from_port   = 3306
        to_port     = 3306
        protocol    = "tcp"
        cidr_blocks = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24" ]
      }
    
      ingress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
    
      ingress {
        from_port   = 80
        to_port     = 80
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
    
      ingress {
        from_port   = 443
        to_port     = 443
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
    
      egress {
        from_port   = 0
        to_port     = 0
        protocol    = "-1"
        cidr_blocks = ["0.0.0.0/0"]
      }
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_subnet" "main_subnet_a" {
      vpc_id            = aws_vpc.main_vpc.id
      cidr_block        = "10.0.1.0/24"
      availability_zone = "us-east-2a"
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_subnet" "main_subnet_b" {
      vpc_id            = aws_vpc.main_vpc.id
      cidr_block        = "10.0.2.0/24"
      availability_zone = "us-east-2b"
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    
    resource "aws_subnet" "main_subnet_c" {
      vpc_id            = aws_vpc.main_vpc.id
      cidr_block        = "10.0.3.0/24"
      availability_zone = "us-east-2c"
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_subnet" "main_subnet_nat_gateway_a" {
      vpc_id            = aws_vpc.main_vpc.id
      cidr_block        = "10.0.4.0/24"
      availability_zone = "us-east-2a"
    }
    
    resource "aws_subnet" "main_subnet_nat_gateway_b" {
      vpc_id = aws_vpc.main_vpc.id
      cidr_block = "10.0.5.0/24"
      availability_zone = "us-east-2b"
    }
    
    resource "aws_subnet" "main_subnet_nat_gateway_c" {
      vpc_id = aws_vpc.main_vpc.id
      cidr_block = "10.0.6.0/24"
      availability_zone = "us-east-2c"
    }
    
    
    resource "aws_db_subnet_group" "db_subnet_group" {
      name        = "db_subnet_group"
      description = "My DB subnet group"
    
      subnet_ids = [
        aws_subnet.main_subnet_a.id,
        aws_subnet.main_subnet_b.id,
        aws_subnet.main_subnet_c.id
      ]
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    
    resource "aws_route_table_association" "subnet-association-a" {
      subnet_id      = aws_subnet.main_subnet_a.id
      route_table_id = aws_route_table.route-table-main.id
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_route_table_association" "subnet-association-b" {
      subnet_id      = aws_subnet.main_subnet_b.id
      route_table_id = aws_route_table.route-table-main.id
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_route_table_association" "subnet-association-c" {
      subnet_id      = aws_subnet.main_subnet_c.id
      route_table_id = aws_route_table.route-table-main.id
    
      lifecycle {
        prevent_destroy = true
      }
    }
    
    resource "aws_route_table_association" "subnet-association-nat-gateway-a" {
      subnet_id = aws_subnet.main_subnet_nat_gateway_a.id
      route_table_id = aws_route_table.route-table-nat.id
    }
    
    
    resource "aws_route_table_association" "subnet-association-nat-gateway-b" {
      subnet_id = aws_subnet.main_subnet_nat_gateway_b.id
      route_table_id = aws_route_table.route-table-nat.id
    }
    
    resource "aws_route_table_association" "subnet-association-nat-gateway-c" {
      subnet_id = aws_subnet.main_subnet_nat_gateway_c.id
      route_table_id = aws_route_table.route-table-nat.id
    }
    
    resource "aws_iam_role" "lambda_exec" {
      name               = "lambda-exec"
      assume_role_policy = <<POLICY
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Service": "lambda.amazonaws.com"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
    POLICY
    }
    
    
    resource "aws_iam_role_policy_attachment" "lambda_policy" {
      role       = aws_iam_role.lambda_exec.name
      policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
    }
    
    resource "aws_iam_role_policy_attachment" "lambda_sns_policy" {
      role       = aws_iam_role.lambda_exec.name
      policy_arn = "arn:aws:iam::aws:policy/AmazonSNSFullAccess"
    }
    
    data "archive_file" "lambda_auth" {
      type = "zip"
    
      source_dir  = "../${path.module}/lambdas/auth"
      output_path = "../${path.module}/lambdas/auth.zip"
    }
    
    resource "aws_s3_object" "lambda_auth" {
      bucket = aws_s3_bucket.lambda_bucket.id
    
      key    = "auth.zip"
      source = data.archive_file.lambda_auth.output_path
    
      etag = filemd5(data.archive_file.lambda_auth.output_path)
    }
    
    resource "aws_lambda_function" "auth_test" {
      function_name = "auth-test"
    
      s3_bucket = aws_s3_bucket.lambda_bucket.id
      s3_key    = aws_s3_object.lambda_auth.key
    
      runtime = "nodejs18.x"
      handler = "index.test"
    
      source_code_hash = data.archive_file.lambda_auth.output_base64sha256
    
      role = aws_iam_role.lambda_exec.arn
    
      environment {
        variables = {
          RDS_DATABASE_NAME = var.database_name
          RDS_DATABASE_HOST = aws_db_instance.cyrannus_database.address
          RDS_DATABASE_USER = aws_db_instance.cyrannus_database.username
          RDS_DATABASE_PASS = aws_db_instance.cyrannus_database.password
        }
      }
    
      vpc_config {
        security_group_ids = [aws_security_group.main_sg.id]
        subnet_ids         = [aws_subnet.main_subnet_nat_gateway_a.id, aws_subnet.main_subnet_nat_gateway_b.id, aws_subnet.main_subnet_nat_gateway_c.id]
      }
    
      timeout = 60
    }
    
    resource "aws_lambda_function" "auth_linkedin_callback" {
      function_name = "auth-linkedin-callback"
    
      s3_bucket = aws_s3_bucket.lambda_bucket.id
      s3_key    = aws_s3_object.lambda_auth.key
    
      runtime = "nodejs18.x"
      handler = "index.linkedinCallback"
    
      source_code_hash = data.archive_file.lambda_auth.output_base64sha256
    
      role = aws_iam_role.lambda_exec.arn
    
      environment {
        variables = {
          RDS_DATABASE_NAME = var.database_name
          RDS_DATABASE_HOST = aws_db_instance.cyrannus_database.address
          RDS_DATABASE_USER = aws_db_instance.cyrannus_database.username
          RDS_DATABASE_PASS = aws_db_instance.cyrannus_database.password
          LINKEDIN_CLIENT_ID = var.linkedin_client_id
          LINKEDIN_CLIENT_SECRET = var.linkedin_client_secret
          LINKEDIN_REDIRECT_URI = "${aws_apigatewayv2_stage.dev.invoke_url}/auth/linkedin/callback"
        }
      }
    
      vpc_config {
        security_group_ids = [aws_security_group.main_sg.id]
        subnet_ids         = [aws_subnet.main_subnet_nat_gateway_a.id, aws_subnet.main_subnet_nat_gateway_b.id, aws_subnet.main_subnet_nat_gateway_c.id]
      }
    
      timeout = 60
    }
    
    
    resource "aws_cloudwatch_log_group" "auth_test" {
      name = "/aws/lambda/${aws_lambda_function.auth_test.function_name}"
    
      retention_in_days = 14
    }
    
    resource "aws_cloudwatch_log_group" "auth_linkedin_callback" {
      name = "/aws/lambda/${aws_lambda_function.auth_linkedin_callback.function_name}"
    
      retention_in_days = 14
    }
    

    我尝试过使用一些教程中介绍的NAT网关,但我有点迷失了方向,AWS控制台界面似乎默认情况下会做很多事情,我不确定我缺少了什么。

    例如,我成功地创建了一个位于专有网络中的EC2来访问位于同一专有网络的RDS,并通过IGW为其提供了网络访问权限,我可以卷曲命令并添加了一个简单的phpmyadmin。

    1 回复  |  直到 2 年前
        1
  •  0
  •   Mark B    2 年前

    您已在具有到NAT网关的路由的子网中放置了一个NAT网关。这是一个循环引用。此子网实际上没有到Internet的路由,因此NAT网关实际上不会工作。

    • 您的NAT网关应该位于有到Internet网关路由的子网中。
    • 您的Lambda函数应该位于有到NAT网关路由的子网中。