"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > Go Serverless REST API를 구축하고 SAM 프레임워크를 사용하여 AWS에 배포(Amazon Linux untime)

Go Serverless REST API를 구축하고 SAM 프레임워크를 사용하여 AWS에 배포(Amazon Linux untime)

2024-09-18에 게시됨
검색:947

또 다른 Go 튜토리얼이 필요한 이유

AWS는 최근 여러 서비스와 런타임을 더 이상 사용하지 않습니다. 우리가 사랑하는 CodeCommit 및 기타 중요한 서비스의 중단을 통해 확인했듯이 Go1.x는 더 이상 AWS Lambda 기능에 대해 지원되지 않습니다.

오래된 튜토리얼 대부분을 배포하려고 하면 다음과 같은 오류가 발생할 수 있습니다.

Resource creation Initiated    
CREATE_FAILED                    AWS::Lambda::Function            DemoFunction                     
                                   Resource handler returned message: 
                                   "The runtime parameter of go1.x is no longer supported for 
                                   creating or updating AWS Lambda functions. We recommend you 
                                   use a supported runtime while creating or updating functions. 
                                   (Service: Lambda, Status Code: 400, Request ID:  
                                   81f1f708-0a7a-40d0-8442-b9c16510d01f)" 
ROLLBACK_IN_PROGRESS             AWS::CloudFormation::Stack       lambda-go-gorilla                
                                   The following resource(s) failed to create: 
                                   [DemoFunction]. Rollback requested by user.

핵심 내용은 소프트웨어에서 변하지 않는 유일한 것은 변화라는 것입니다. 그러나 우리가 항상 명심해야 할 몇 가지 시대를 초월한 원칙이 있습니다:

이 문제를 해결하기 위해 저는 Go 애플리케이션을 배포하는 데 필요한 모든 인프라를 갖춘 최신 저장소를 만들기로 결정했습니다. 다음 두 가지 옵션을 사용할 수 있습니다.

  1. Docker 컨테이너를 사용하여 Fargate로 배포
  2. AWS에서 SAM 프레임워크를 사용하여 배포합니다.

GitHub에서 저장소를 여기에서 찾을 수 있습니다.

소프트웨어 개발의 시대를 초월한 원칙

  • 코드로서의 인프라는 필수적입니다.
  • 소프트웨어에서는 올바른 명명 규칙이 중요합니다.
  • 항상 논리를 테스트하세요.
  • 가용성 및 확장성
  • 소프트웨어 제공 프로세스를 자동화하는 메커니즘인 배포 파이프라인.
  • 관측성은 필수입니다.
  • 보안은 클라우드 네이티브 애플리케이션의 최우선 요소입니다.
  • Go는 API 구축을 위한 탁월한 옵션입니다.

코드형 인프라는 필수입니다

불변 인프라를 통해 우리가 원하는 것을 더 높은 수준에서 선언할 수 있으며 개발 및 프로덕션 환경이 최대한 가깝게 유지되도록 보장합니다. 예를 들어:

CompoundingFunction:
  Type: AWS::Serverless::Function
  Metadata:
    BuildMethod: makefile
  Properties:
    FunctionName: CompoundingFunction
    Architectures: ["arm64"]
    Handler: bootstrap
    Runtime: provided.al2
    CodeUri: ./functions/CompoundingFunction/
    MemorySize: 512
    Timeout: 10
    Environment:
      Variables:
        COMPOUNDING_TABLE_NAME: !Ref CompoundingTable
    Policies:
      - DynamoDBCrudPolicy:
          TableName: !Ref CompoundingTable
    Events:
      ApiGatewayPost:
        Type: Api
        Properties:
          RestApiId: !Ref ApiGateway
          Path: /compounding
          Method: POST

소프트웨어의 좋은 명명 규칙이 핵심입니다

좋은 테스트 세트가 있다면 리팩터링을 두려워하지 마세요. 리팩토링은 소프트웨어 개발에 있어 필수적인 활동입니다. 이름은 모듈, 함수, 패키지, 변수 등 모든 곳에 나타나므로 중요합니다.

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
)

// Response is the structure for the response JSON
type Response struct {
    Message      string    `json:"message"`
    GainsPerYear []float64 `json:"gainsPerYear"`
}

type Request struct {
    Principal  float64 `json:"principal"`
    AnnualRate float64 `json:"annualRate"`
    Years      int     `json:"years"`
}

func HelloHandler(ctx context.Context, event events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    var req Request
    err := json.Unmarshal([]byte(event.Body), &req)
    if err != nil {
        return createResponse(400, "Invalid request body")
    }
    fmt.Println("Request", req)
    gainsPerYear := CalculateCompoundInterest(req.Principal, req.AnnualRate, req.Years)
    fmt.Println(gainsPerYear)
    response := Response{
        Message:      "Calculation successful",
        GainsPerYear: gainsPerYear,
    }

    body, err := json.Marshal(response)
    if err != nil {
        return createResponse(500, "Error marshalling response")
    }

    return createResponse(200, string(body))
}

func createResponse(statusCode int, body string) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        StatusCode: statusCode,
        Body:       body,
        Headers:    map[string]string{"Content-Type": "application/json"},
    }, nil
}

func main() {
    lambda.Start(HelloHandler)
}

항상 논리를 테스트하세요

서버리스 애플리케이션에서는 단위 테스트가 중요하지만 통합 테스트도 포함하는 것을 잊지 마세요. 이러한 애플리케이션의 대부분은 비즈니스 문제를 해결하기 위해 통합 및 정책에 의존하기 때문입니다.

func TestCalculateCompoundInterest(t *testing.T) {
    principal := 100000000.0
    annualRate := 10.0
    years := 10

    result := CalculateCompoundInterest(principal, annualRate, years)
    lastElement := round(result[len(result)-1], 2)

    expected := round(259374246.01, 2)
    if !reflect.DeepEqual(lastElement, expected) {
        t.Errorf("Expected %v, but got %v", expected, lastElement)
    }
}

가용성 및 확장성

서버리스 아키텍처는 기본적으로 가용성이 높으며 이벤트 기반이므로 대부분의 운영 작업이 제거됩니다. 그러나 ECS와 컨테이너를 사용하기로 선택한 경우 로드 밸런서를 포함하여 서버 간에 트래픽을 분산시켜 가용성과 확장성을 모두 보장하는 것이 중요합니다.

  CompoundingLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: compounding-nlb
      Scheme: internet-facing
      Type: network
      Subnets:
        - !Ref PublicSubnetOne
        - !Ref PublicSubnetTwo

배포 파이프라인

배포 파이프라인은 소프트웨어 제공 프로세스를 자동화합니다. 우리는 이 프로세스를 단순화하기 위해 Makefile을 만들었습니다. 이를 통해 단일 명령으로 반복적인 작업을 쉽게 배포하고 실행할 수 있습니다. 이 접근 방식은 배포 워크플로의 효율성과 일관성을 향상시킵니다.

Build Go Serverless REST APIs and Deploy to AWS using the SAM framework (Amazon Linux untime)

관찰 가능성은 필수입니다

추적, 로깅, 지표가 마련되어 있는지 확인하세요. 서버리스 애플리케이션을 사용하면 Tracing: Active를 추가하는 것만큼 간단하게 이러한 기능을 활성화할 수 있습니다. CloudWatch와 같은 중앙 위치에서 모든 로그를 확인하고 서비스 상호 작용을 모니터링하는 기능은 매우 중요합니다.

Build Go Serverless REST APIs and Deploy to AWS using the SAM framework (Amazon Linux untime)

보안은 클라우드 네이티브 애플리케이션의 최우선 요소입니다

보안은 모든 애플리케이션에서 가장 중요합니다. Amazon Cognito를 사용하면 강력한 사용자 인증이 제공되고, API 키는 추가 제어 및 인증 계층을 추가하여 인증된 클라이언트만 API에 액세스할 수 있도록 보장합니다.

Auth:
  DefaultAuthorizer: CompoundingAuthorizer
  Authorizers:
    CompoundingAuthorizer:
      UserPoolArn:  XXXX
    LambdaTokenAuthorizer:
      FunctionArn: !GetAtt LambdaTokenAuthorizerFunction.Arn
      FunctionPayloadType: REQUEST
      Identity:
        Headers:
          - Authorization
        ReauthorizeEvery: 100
  AddDefaultAuthorizerToCorsPreflight: false

각 서비스, 사용자 및 구성 요소에 최소한의 필수 권한을 할당하여 공격 표면을 줄이고 무단 액세스를 방지합니다. 최소 권한 원칙:

      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref CompoundingTable

참고자료

  1. Terraform 실행 - 인프라 구축, 변경, 관리를 위한 도구인 Terraform 구현을 위한 실제 사용 및 전략
  2. 지속적 전달 파이프라인

결론

소프트웨어는 지속적으로 발전하고 있으며 일부 도구와 방식은 변경되지만 기본 원칙은 동일하게 유지됩니다. 불변의 인프라, CI/CD, 올바른 명명 규칙, 강력한 테스트 전략, API의 보안, 애플리케이션의 효율성이 필요합니다. 그래서 이 프로젝트를 서버리스 방식으로 다시 만들기로 결정했습니다.

엔지니어가 되어 소프트웨어를 통해 사회에 가치를 창출하기에 이보다 더 좋은 때는 없었습니다.

  • 링크드인
  • 지저귀다
  • GitHub

기사가 마음에 드셨다면 제 블로그 jorgetovar.dev를 방문해 주세요.

릴리스 선언문 이 문서는 https://dev.to/aws-builders/build-go-serverless-rest-apis-and-deploy-to-aws-using-the-sam-framework-amazon-linux-2-에 재현되어 있습니다. 런타임- 4n5p?1 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제해 주시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3