티스토리 뷰

앞서 이야기했지만 Go도 알아야되는 상황이 됐다.

 

그 이유는 Go로 개발한 Lambda가 있기 때문이다.

 

아무것도 몰라서 바닥부터 머리를 박아가면서 알게된것들이 많다.

 

Go로 Lambda를 개발할 때 주의할 점이 몇가지 있다.

1. yarn이나 npm 같은 패키지매니저가 없어서 makefile을 이용해 빌드 방식을 관리한다.
2. 올해(2024년)부터는 runtime을 go 1.x보다 Amazon Linux 2를 사용하길 권장한다. 
3. binary를 생성하고, Amazon Linux 2에서 사용되는 bootstrap으로 람다에 배포해야한다.

 

참고자료 : https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/golang-package.html

 

추가적으로, Go의 함수 크기가 nodejs보다 커서 함수를 Lambda 콘솔 내에서 관리할 수 없다.

 

이제 위 내용을 하나씩 시작해볼텐데,

 

내 개발 환경은 Windows 10 WSL이고, Lambda 관리를 위해서 serverless framework를 사용할 것이다.

 

Go 설치는 이전 글에서 확인할 수 있다.

 

그냥 Lambda만 만들면 재미가 없으니 이번에는 S3를 연동해보자.  

 

Go를 사용하는 serverless 프로젝트 생성

serverless 설치 과정. 기본 환경은 WSL이다. 

$ serverless create --template aws-go --path ./serverless-go-lambda

위 명령어를 입력하면 아래와 같이 파일들이 생성된다.

 

이렇게 프로젝트가 생성됨

 

nodejs와 가장 큰 차이점은 Makefile이 생긴다는 점이다.

 

Makefile은 바이너리 파일을 만들 때 사용할 것이니 일단 두고, serverless.yml을 확인해보자.

 

serverless.yml 작성

serverless.yml 파일을 열어보면 주석이 많다. 다 지우고보면 코드가 몇 줄 안 남는다.

 

자동 생성된 serverless.yml

service: serverless-go-lambda
frameworkVersion: '3'

provider:
  name: aws
  runtime: go1.x
  
package:
  patterns:
    - '!./**'
    - ./bin/**

functions:
  hello:
    handler: bin/hello
    events:
      - httpApi:
          path: /hello
          method: get
  world:
    handler: bin/world
    events:
      - httpApi:
          path: /world
          method: get

hello랑 world는 사용하지 않을 함수라 삭제해주고, 새로운 이름의 함수를 만들어 준다.(API Gateway 도 사용 X)

 

그리고, 위에서 언급했듯이 runtime으로 go1.x를 사용할 수 없다. provided.al2로 변경해준다. provided.al2가 Amazon Linux 2 이다.

 

s3를 사용하기 때문에, IAM role을 지정해준다.

 

그리고 bootstrap을 사용해야하므로, 함수의 handler가 bootstrap이 된다.

 

태그는 이번엔 생략했다.

 

변경 후 serverless.yml

service: serverless-go-lambda
frameworkVersion: '3'

provider:
  name: aws
  region: ap-northeast-2
  architecture: arm64
  runtime: provided.al2
  memorySize: 256
  timeout: 10
  environment:
    S3_BUCKET: testbed-lambda-bucket
  deploymentBucket:
    name: testbed-lambda-deploy-bucket
  logRetentionInDays: 30
  iam:
    role:
      name: testbed-s3-role
      path: /lambda/
      statements:
        - Effect: Allow
          Resource: arn:aws:s3:::testbed-lambda-bucket/*
          Action: s3:PutObject

functions:
  go_function:
    name: serverless-go-lambda
    handler: bootstrap
    package:
      patterns:
        - 'bootstrap'
    url: true

IAM은 자동으로 생성된다.

 

testbed-s3-role을 찾아가면, 생성된 역할과 정책을 확인할 수 있다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogStream",
                "logs:CreateLogGroup",
                "logs:TagResource"
            ],
            "Resource": [
                "arn:aws:logs:ap-northeast-2:301591718339:log-group:/aws/lambda/serverless-go-lambda:*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:ap-northeast-2:301591718339:log-group:/aws/lambda/serverless-go-lambda:*:*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::testbed-lambda-bucket/*",
            "Effect": "Allow"
        }
    ]
}

log에 관한 정책은 자동 생성된다. 그리고, yaml 파일에 작성한 s3 bucket putObject 허용한 정책도 확인할 수 있다.

 

S3 버킷 생성

배포 전에, S3를 사용하기 위해서 bucket 두 개를 만들어 줘야한다.

 

하나는 serverless 배포 파일이 들어갈 곳, 그리고 하나는 람다에서 만든 txt 파일이 들어갈 곳이다.

S3 디폴트 설정으로 두개를 만들었다.

 

Go 코드 작성

./lambda/main.go에 코드를 작성함

 

그전에 모듈을 init하고 코드에서 사용할 모듈들을 불러와야한다.

go mod init serverless-go-lambda
go get "github.com/aws/aws-sdk-go-v2/aws"
go get "github.com/aws/aws-lambda-go/events"
go get "github.com/aws/aws-sdk-go-v2/service/s3"
go get "github.com/aws/aws-lambda-go/lambda"
go get "github.com/aws/aws-sdk-go-v2/config"
go get "github.com/rs/zerolog/log"

 

Go 코드는 별게 없다. 

 

주의할게 딱 하나 있는데, Lambda 내부에서 write가 가능한 곳은 /tmp 아래밖에 없다.

 

이거만 주의하면 된다. 나머진 텍스트 파일을 만들고 aws sdk를 이용해 S3에 putObject하는게 끝이다.

 

코드는 여기서 확인

Makefile 작성

빌드를 위해 makefile을 작성해야한다.

 

설치가 안되어있다면 make를 설치

sudo apt-get update
sudo apt-get install make

자동생성된 파일은 그냥 삭제하고 다시 만들었다.

.PHONY: build-lambda
build-lambda: clean
	CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -tags lambda.norpc -ldflags '-s -w' -trimpath \
		-o bootstrap lambda/main.go

.PHONY: clean
clean: go clean
	rm -f bootstrap

.PHONY: deploy-function
deploy-function: build-lambda
	sls deploy function -f go_function

.PHONY: deploy
deploy: build-lambda
	sls deploy --verbose

lambda/main.go를 bootstrap이란 파일명으로 바이너리 파일로 빌드하고, 배포하는 과정이다.

 

명령어들은 어렵지 않다.

make build-lambda # 바이너리 파일 생성
make clean # 경로의 go 설정과 boostrap 파일 삭제
make deploy-function # 함수만 배포
make deploy # 전체 배포

 

make deploy로 배포한다.

 

AWS Lambda 확인

런타임이 Amazon Linux 2로 만들어진 함수를 확인 할 수 있다.

 

별도의 트리거를 만들지 않았으므로, 함수가 정상적으로 동작하는지 확인해보기 위해서는 URL을 통해 람다에 접근해야한다.

함수 URL을 클릭하면 람다를 실행할 수 있다.

결과 확인

URL에 접근하면 미리 입력해둔 response가 나온다.

 

파일을 다운받아서 열어보면 내가 입력한 문자열이 정상적으로 저장된 것을 확인 할 수 있다.

github

https://github.com/imsosleepy/serverless-lambda/tree/main/serverless-go-lambda

마치며

이제 이미지 리사이징을 위해 사용한 람다 엣지만 보면 람다는 거의 다 본 것 같다.

 

serverless와 람다는 한동안 볼일이 없었으면 좋겠다...

 

terraform과 eks가 진입장벽이 좀 있어서 손에 잡히는 일들을 먼저 처리하다보니 공부가 조금씩 늦어지고 있다.

 

중요도가 가장 높은걸 계속해서 미루니 속이 좋지 않다.

 

람다 엣지까지만 정리하고, 테라폼과 쿠버네티스를 시작해야할 것 같다.

 

참고

https://devlifetestcase.tistory.com/55

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함