본문 바로가기
Web development/Infra

Azure Pipeline node.js 람다 배포 템플릿 만들기

by 자몬다 2020. 9. 11.

구축하려는 Pipeline 과정은 다음과 같다.

1. Azure Repo의 특정 branch에 변경사항이 반영되면 Pipeline이 트리거된다.

2. ubuntu vm환경에서 작동하도록 한다.

3. Node와 Npm을 설치한다. (npm install을 위해)

4. 모듈 설치를 위해 npm install 한다.

5. 배포에 필요없는 파일들을 삭제한다. (azure-pipelines.yml 등)

6. 배포 패키지를 만들기 위해 압축한다.

7. S3에 업로드한다.

8. S3에 업로드된 파일을 사용해 람다에 배포한다.

 

리포지토리의 구조는 아래와 같다.

test-repo

ㄴindex.js

ㄴazure-pipelines.yml

ㄴpackage.json

ㄴ.gitignore

 

아직 파이프라인을 구축한 적이 없다면 azure-pipelines.yml은 없을수도 있다.

생성해주면 된다.

 

일단 완성된 azure-pipelines.yml을 보자.

trigger:
- develop

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: NodeAndNpmTool@1
  inputs:
    versionSpec: '10.x'
    
- task: Npm@1
  inputs:
    command: 'install'
    workingDir: '$(Build.SourcesDirectory)'
    
- task: DeleteFiles@1
  displayName: 'Remove unneeded files'
  inputs:
    contents: |
      azure-pipelines.yml
      *.json
      .git*
      
- task: ArchiveFiles@2
  inputs:
    rootFolderOrFile: '$(Build.SourcesDirectory)'
    includeRootFolder: false
    archiveType: 'zip'
    archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip'
    replaceExistingArchive: true

- task: S3Upload@1
  inputs:
    awsCredentials: '[DevOps Service Connections에 추가되어 있는 credential의 이름]'
    regionName: '[리전 이름]'
    bucketName: '[버킷 이름]'
    sourceFolder: '$(Build.ArtifactStagingDirectory)'
    globExpressions: '$(Build.BuildId).zip'
    filesAcl: 'public-read'
    createBucket: true
    
- task: LambdaDeployFunction@1
  inputs:
    awsCredentials: '[DevOps Service Connections에 추가되어 있는 credential의 이름]'
    regionName: '[리전 이름]'
    deploymentMode: 'codeonly'
    functionName: '[람다 이름]'
    codeLocation: 's3object'
    s3Bucket: '[버킷 이름]'
    s3ObjectKey: '$(Build.BuildId).zip'

 

하나씩 짚어보자.

 

1. Azure Repo의 특정 branch에 변경사항이 반영되면 Pipeline이 트리거된다.

trigger:
- master

이 파이프라인이 트리거될 브랜치를 지정한다.

 

2. ubuntu vm환경에서 작동하도록 한다.

pool:
    vmImage: 'ubuntu-latest'

 

3. Node와 Npm을 설치한다. (npm install을 위해)

steps:
- task: NodeAndNpmTool@1
    inputs:
        versionSpec: '10.x' # node 10버전을 사용한다.

 

4. 모듈 설치를 위해 npm install 한다.

- task: Npm@1
   inputs:
      command: 'install' # npm install이 실행된다.
      workingDir: '$(Build.SourcesDirectory)' # 명령어가 실행될 디렉토리

 

5. 배포에 필요없는 파일들을 삭제한다. (azure-pipelines.yml 등)

- task: DeleteFiles@1
   displayName: 'Remove unneeded files'
   inputs:
      contents: |
         azure-pipelines.yml # 삭제할 파일들의 형식
         *.json
         .git*

내 경우 npm install로 생성된 /node-modules와 index.js만을 배포하고 싶었으므로,

azure-pipelines.yml과 package.json, package-lock.json을 삭제하도록 했다.

.gitignore와 .git도 올라가지 않았으면 해서, .git으로 시작하는 파일 및 디렉토리도 삭제하도록 했다.

참고 : docs.microsoft.com/en-us/azure/devops/pipelines/tasks/utility/delete-files?view=azure-devops

 

6. 배포 패키지를 만들기 위해 압축한다.

- task: ArchiveFiles@2
   inputs:
      rootFolderOrFile: '$(Build.SourcesDirectory)' # 작업할 디렉토리 또는 파일
      includeRootFolder: false # 루트 폴더를 포함할 것인지?
      archiveType: 'zip'
      archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip' # 압축한 파일을 저장할 경로
      replaceExistingArchive: true # 이미 존재하는 경우 덮어쓸 것인지

 

7. S3에 업로드한다.

- task: S3Upload@1
   inputs:
      awsCredentials: 'Sample Credential Name' # DevOps에 등록되어 있는 aws Credential 이름 
      regionName: 'ap-northeast-2' # S3 리전 
      bucketName: 'test-bucket' # 버킷 이름
      sourceFolder: '$(Build.ArtifactStagingDirectory)' # 어디에 있는 파일을 S3에 올릴 것인지?
      globExpressions: '$(Build.BuildId).zip' # 업로드할 파일의 표현식
      filesAcl: 'public-read' # 파일 읽기 정책
      createBucket: true # 버킷이 없으면 생성할 것인지?

 

8. S3에 업로드된 파일을 사용해 람다에 배포한다.

- task: LambdaDeployFunction@1
   inputs:
      awsCredentials: 'Sample Credential Name' # DevOps에 등록되어 있는 aws Credential 이름 
      regionName: 'ap-northeast-2' # Lambda 리전
      deploymentMode: 'codeonly' # 코드만 배포할 것인지, 아니면 config를 함께 배포할 것인지?
      functionName: 'sample-function-name' # 람다 이름 
      codeLocation: 's3object' # 코드의 위치. 로컬에서 바로 올릴 수도 있고, S3를 통해 올릴수도 있다.
      s3Bucket: 'test-bucket' # 버킷 이름
      s3ObjectKey: '$(Build.BuildId).zip' # S3에 저장된 파일의 키(이름)

 


파일을 압축하고 S3에 업로드하는 부분에서 많이 헤맸다.

내 리포지토리에서는 리포지토리가 루트 폴더고, 폴더 안에는 배포할 파일들밖에 없는데

실제 배포를 할때는 경로가 다르기 때문이다.

배포하는 환경의 디렉토리와 Pipeline에서 사용하는 환경변수를 잘 몰랐기 때문인데, 

pipeline에 script로 경로와 환경변수를 찍어보고, 문서를 참고하니 해결할 수 있었다.

 

 

/home/vsts/work/1/s = $(Build.SourcesDirectory) = task 실행시 디렉토리 경로

/home/vsts/work/1/b = $(Build.BinariesDirectory)

/home/vsts/work/1/a = $(Build.ArtifactStagingDirectory)

123 = $(Build.BuildId) = 빌드 번호. 새로 빌드할때마다 1씩 올라감

 

내가 원했던 것은 /s에 있는 파일들을 /a/123.zip 으로 저장한 뒤 S3에 업로드하는 것이어서 

원하는 환경변수를 적절히 사용했다.

 

확인하는 방법은 아래와 같은 방식으로 하면 된다. task와 같은 depth에 추가해주면 됨.

- script: |
      pwd
      ls -al
      echo $(Build.BinariesDirectory)
   displayName: check directory

다른 환경변수들은 문서에서 확인가능하다.

docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml

 

 

* 더 좋은 방법이 있을 수 있고, 틀린 부분이 있을 수 있습니다. 참고만 해주세요. 피드백은 환영합니다!

댓글