BLOG

AWS Step Functions와 AWS CodeBuild 서비스 통합 지원…애플리케이션의 연속 통합 워크플로를 더 빠르게 구축 가능
작성일: 2020-05-27

소프트웨어 빌드 자동화는 DevOps 모범 사례를 도입하기 위한 중요한 단계입니다. 이를 위해 AWS는 소스 코드 번역, 테스트 실행, 및 배포 준비가 된 패키지를 생산하는 완전 관리 CI AWS CodeBuild와 배포 파이프라인을 자동화하는 완전 관리 CD서비스 AWS CodePipeline를 만들었습니다.

 

고객의 구축 프로세스에 맞게 적용 가능한 맞춤형 옵션 또한 제공됩니다. 개발자가 소프트웨어 구축에 필요한 다양한 활동을 조정하기 위해 자체 사용자 정의 워크 플로우를 작성하는 데 시간을 할애하는 것을 알게 되었습니다. 빠른 수정을 배포해야 할 때 일부 테스트를 실행하거나 코드의 정적 분석을 건너뛰고 싶으실 수 있습니다. 단위 테스트 결과에 따라 다른 조치를 취하거나 SNS 를 통해 알림을 받고 싶을 수도 있습니다.

 

CodePipeline으로 쉽게 구현할 수 없는 복잡한 사용 사례를 단순화하기 위해  CodeBuild로 새로운 AWS Step Functions service integration을 런칭했습니다. 이제 상태 머신을 실행하는 동안  구축을 시작 또는  중지하고 구축 보고서 요약을 가져오고 과거 빌드 실행 레코드를 삭제할 수 있습니다.

 

이러한 방식으로 고유한 워크 플로우 중심 구축 프로세스 정의하고 수동 또는 자동으로 트리거할 수 있습니다. 이를 통해 다음을 수행할 수 있습니다.

 

  • Amazon EventBridge 규칙을 사용하여 주기적으로 (야간 구축의 경우) 워크플로우를 시작하려는 경우 또는 무언가 발생하는 경우 (AWS CodeCommit 리포지토리에 대한 풀 요청과 같은) 빌드 워크 플로우를 시작하세요.
  • 워크플로우를 시작하기 전 입력 페이로드의 유효성을 확인하는 AWS Lambda 함수를 통하거나 상태 머신에 직접 통합하여 Amazon API Gateway를 사용하는 GitHub와 같은 서비스를 호출하는 webhook를 구축합니다.
  • 해당 링크의 게시물에 설명된 대로 AWS CodePipeline 작업의 동작을 사용자 지정하세요.

 

이 통합을 통해 Step Functions 의 모든 기능을 사용 하여 소프트웨어 구축을 자동화할 수 있습니다. 예를 들어, Parallel상태를 사용하여 빌드의 독립 구성 요소에 대한 병렬 빌드를 만들 수 있습니다. 코드 리포지토리의 모든 브런치 목록에서 시작하여 Map상태를 사용하여 각 브런치에 대해 필요 단계 (자동화 빌드, 단위 테스트 및 통합 테스트)를 실행할 수 있습니다. 다른 Step Functions 서비스 통합과 동일한 워크 플로우를 활용할 수도 있습니다.  예를 들어, 활동을 추적하기 위해 SQS 대기열에 메시지를 보내거나 Amazon ECS 및 AWS Fargate를 사용하여 구축한 컨테이너형 애플리케이션을 시작할 수 있습니다.

 

 

워크 플로우 중심 빌드 프로세스에 단계 함수 사용

Java 웹 애플리케이션을 작업 중이라고 가정해 보겠습니다. 새로운 기능을 추가할 때 작동하는지 확인하기 위해 JUnit Jupiter를 사용하여 몇 가지 테스트를 작성했습니다. 테스트가 구축 프로세스 직후에 실행되도록 하고 싶지만 테스트가 빠른 반복을 느리게 할 수 있기 때문에 상황에 맞게 진행해야 합니다. 테스트를 실행할 때 CodeBuild를 사용하여 테스트 보고서 저장하고 확인하고자하며 마지막으로 테스트가 실행되고 성공한 경우 SNS 로부터 알림을 받고자 합니다.

 

CodeCommit에 리포지토리를 만들고 CodeBuild에 대한 두 개의 buildspec 파일을 포함 시켰습니다.

 

  • buildspec.yml기본값이며 Apache Maven을 사용하여 빌드 및 테스트를 실행한 다음 테스트 결과를 보고서로 저장합니다.

version: 0.2

phases:

  build:

    commands:

      mvn package

artifacts:

  files:

    target/binaryconverter1.0SNAPSHOT.jar

reports:

  SurefireReports:

    files:

      ‘**/*’

    base-directory: ‘target/surefire-reports’

 

 

  • buildspec-notests.yml 는 구축만하고 테스트는 실행되지 않습니다.

version: 0.2

phases:

  build:

    commands:

      mvn package DskipTests

artifacts:

  files:

    target/binaryconverter1.0SNAPSHOT.jar

 

 

구축을 자동화 하도록 CodeBuild 프로젝트와 Step Functions 상태 시스템을 설정하려면 다음 템플릿과 함께 AWS CloudFormation을 사용합니다.

AWSTemplateFormatVersion: 2010-09-09

Description: AWS Step Functions sample project for getting notified on AWS CodeBuild test report results

Resources:

  CodeBuildStateMachine:

    Type: AWS::StepFunctions::StateMachine

    Properties:

      RoleArn: !GetAtt [ CodeBuildExecutionRole, Arn ]

      DefinitionString:

        !Sub

          – |-

            {

              “Comment”: “An example of using CodeBuild to run (or not run) tests, get test results and send a notification.”,

              “StartAt”: “Run Tests?”,

              “States”: {

                “Run Tests?”: {

                  “Type”: “Choice”,

                  “Choices”: [

                    {

                      “Variable”: “$.tests”,

                      “BooleanEquals”: false,

                      “Next”: “Trigger CodeBuild Build Without Tests”

                    }

                  ],

                  “Default”: “Trigger CodeBuild Build With Tests”

                },

                “Trigger CodeBuild Build With Tests”: {

                  “Type”: “Task”,

                  “Resource”: “arn:${AWS::Partition}:states:::codebuild:startBuild.sync”,

                  “Parameters”: {

                    “ProjectName”: “${projectName}”

                  },

                  “Next”: “Get Test Results”

                },

                “Trigger CodeBuild Build Without Tests”: {

                  “Type”: “Task”,

                  “Resource”: “arn:${AWS::Partition}:states:::codebuild:startBuild.sync”,

                  “Parameters”: {

                    “ProjectName”: “${projectName}”,

                    “BuildspecOverride”: “buildspec-notests.yml”

                  },

                  “Next”: “Notify No Tests”

                },

                “Get Test Results”: {

                  “Type”: “Task”,

                  “Resource”: “arn:${AWS::Partition}:states:::codebuild:batchGetReports”,

                  “Parameters”: {

                    “ReportArns.$”: “$.Build.ReportArns”

                  },

                  “Next”: “All Tests Passed?”

                },

                “All Tests Passed?”: {

                  “Type”: “Choice”,

                  “Choices”: [

                    {

                      “Variable”: “$.Reports[0].Status”,

                      “StringEquals”: “SUCCEEDED”,

                      “Next”: “Notify Success”

                    }

                  ],

                  “Default”: “Notify Failure”

                },

                “Notify Success”: {

                  “Type”: “Task”,

                  “Resource”: “arn:${AWS::Partition}:states:::sns:publish”,

                  “Parameters”: {

                    “Message”: “CodeBuild build tests succeeded”,

                    “TopicArn”: “${snsTopicArn}”

                  },

                  “End”: true

                },

                “Notify Failure”: {

                  “Type”: “Task”,

                  “Resource”: “arn:${AWS::Partition}:states:::sns:publish”,

                  “Parameters”: {

                    “Message”: “CodeBuild build tests failed”,

                    “TopicArn”: “${snsTopicArn}”

                  },

                  “End”: true

                },

                “Notify No Tests”: {

                  “Type”: “Task”,

                  “Resource”: “arn:${AWS::Partition}:states:::sns:publish”,

                  “Parameters”: {

                    “Message”: “CodeBuild build without tests”,

                    “TopicArn”: “${snsTopicArn}”

                  },

                  “End”: true

                }

              }

            }

          – {snsTopicArn: !Ref SNSTopic, projectName: !Ref CodeBuildProject}

  SNSTopic:

    Type: AWS::SNS::Topic

  CodeBuildProject:

    Type: AWS::CodeBuild::Project

    Properties:

      ServiceRole: !Ref CodeBuildServiceRole

      Artifacts:

        Type: NO_ARTIFACTS

      Environment:

        Type: LINUX_CONTAINER

        ComputeType: BUILD_GENERAL1_SMALL

        Image: aws/codebuild/standard:2.0

      Source:

        Type: CODECOMMIT

        Location: https://git-codecommit.us-east-1.amazonaws.com/v1/repos/binary-converter

  CodeBuildExecutionRole:

    Type: “AWS::IAM::Role”

    Properties:

      AssumeRolePolicyDocument:

        Version: “2012-10-17”

        Statement:

          – Effect: Allow

            Action: “sts:AssumeRole”

            Principal:

              Service: states.amazonaws.com

      Path: “/”

      Policies:

        – PolicyName: CodeBuildExecutionRolePolicy

          PolicyDocument:

            Version: “2012-10-17”

            Statement:

              – Effect: Allow

                Action:

                  – “sns:Publish”

                Resource:

                  – !Ref SNSTopic

              – Effect: Allow

                Action:

                  – “codebuild:StartBuild”

                  – “codebuild:StopBuild”

                  – “codebuild:BatchGetBuilds”

                  – “codebuild:BatchGetReports”

                Resource: “*”

              – Effect: Allow

                Action:

                  – “events:PutTargets”

                  – “events:PutRule”

                  – “events:DescribeRule”

                Resource:

                  – !Sub “arn:${AWS::Partition}:events:${AWS::Region}:${AWS::AccountId}:rule/StepFunctionsGetEventForCodeBuildStartBuildRule”

  CodeBuildServiceRole:

    Type: AWS::IAM::Role

    Properties:

      AssumeRolePolicyDocument:

        Version: “2012-10-17”

        Statement:

          – Effect: Allow

            Action: “sts:AssumeRole”

            Effect: Allow

            Principal:

              Service: codebuild.amazonaws.com

      Path: /

      Policies:

        – PolicyName: CodeBuildServiceRolePolicy

          PolicyDocument:

            Version: “2012-10-17”

            Statement:

              – Effect: Allow

                Action:

                – “logs:CreateLogGroup”

                – “logs:CreateLogStream”

                – “logs:PutLogEvents”

                – “codebuild:CreateReportGroup”

                – “codebuild:CreateReport”

                – “codebuild:UpdateReport”

                – “codebuild:BatchPutTestCases”

                – “codecommit:GitPull”

                Resource: “*”

Outputs:

  StateMachineArn:

    Value: !Ref CodeBuildStateMachine

  ExecutionInput:

    Description: Sample input to StartExecution.

    Value:

      >

        {}

 

CloudFormation이 생성되면 상태 머신에 두 가지 CodeBuild가 생깁니다:

  • 첫 번째 CodeBuild 작업은 동기 통합 ( startBuild.sync)을 사용하여 다음 단계로 진행하기 전에 빌드가 종료될 때까지 자동으로 대기합니다.

 

“Trigger CodeBuild Build With Tests”: {

  “Type”: “Task”,

  “Resource”: “arn:aws:states:::codebuild:startBuild.sync”,

  “Parameters”: {

    “ProjectName”: “CodeBuildProject-HaVamwTeX8kM”

  },

  “Next”: “Get Test Results”

}

 

  • 두 번째 CodeBuild 작업은 BuildspecOverride매개 변수를  사용하여 테스트를 실행하지 않는 빌드에서 사용되는 기본 buildspec 파일 을 재정의합니다 .

“Trigger CodeBuild Build Without Tests”: {

  “Type”: “Task”,

  “Resource”: “arn:aws:states:::codebuild:startBuild.sync”,

  “Parameters”: {

    “ProjectName”: “CodeBuildProject-HaVamwTeX8kM”,

    “BuildspecOverride”: “buildspec-notests.yml”

  },

  “Next”: “Notify No Tests”

},

 

 

첫 번째 단계는 Choice테스트를 실행할지 여부를 결정하기 위해 상태 머신 실행의 입력을 조사하는 것입니다. 예를 들어 테스트를 실행하려면 이렇게 입력할 수 있습니다.

{

  “tests”: true

}

 

이것은 테스트 실행 실행의 시각적 워크 플로우이며 모든 테스트가 통과됩니다.

 

값 “tests” 를 false로 변경하고 다른 브런치에 도달하는 새로운 실행을 시작합니다.

 

이번에는 buildspec 이 테스트를 실행하지 않고 테스트가 실행되지 않았다는 알림을 받습니다.

 

GitHub 또는 CodeCommit 에서 활동한 후 이 워크 플로우를 자동으로 시작할 때 특정 패턴에 대한 마지막 커밋 메시지를 보고 그에 따라 빌드 프로세스를 사용자 정의할 수 있습니다. 예를 들어, [skip tests] 문자열이 커밋 메시지의 일부인 경우 테스트를 건너뛸 수 있습니다. 마찬가지로 프로덕션 환경에서 [skip static analysis]메시지가 커밋에 포함되어 있으면 긴급 변경 사항에 대한 빠른 통합을 위해 코드 정적 분석을 건너 뛸 수 있습니다.

 

 

컨테이너화 애플리케이션의 워크플로 확장

애플리케이션을 다른 환경에 배포하는 가장 좋은 방법은 애플리케이션을 Docker 이미지로 패키지하는 것 입니다. 이러한 방식으로 QA(Quality Assurance) 팀을 위해 빌드 워크 플로우에 단계를 추가하고 Amazon ECS 작업(AWS Fargate에서 실행)에서 컨테이너화된 애플리케이션을 시작할 수도 있습니다.

 

먼저, 여기에 설명 된대로 ECR 에서 이미지 저장소를 작성하고 CodeBuild 프로젝트에서 ECR에 업로드하기 위해 사용하는 서비스 역할에 권한을 추가합니다.

 

그런 다음 코드 저장소에서 다음 예제를 따라 추가하세요.

 

  • 애플리케이션을 구축하고 시작하는 소프트웨어가 있는 도커 컨테이너를 준비하는 Dockerfile
  • Docker 이미지를 만들고 업로드하는 명령이 있는 파일 buildspec-docker.yml

 

최종 워크 플로우는 다음 단계를 모두 자동화 합니다.

  1. 소스 코드에서 소프트웨어 구축
  2. Docker 이미지 생성
  3. Docker 이미지를 ECR에 업로드
  4. 에 QA 환경 시작 ECS 와 Fargate .
  5. QA 환경이 준비되었다는 SNS 알림 전송

 

요구 사항에 따라 워크 플로 및 단계를 쉽게 사용자 지정할 수 있습니다. 예를 들어, 약간의 변경으로 buildspec 파일을 조정하여 이미지를 Docker Hub로 푸시할 수 있습니다.

 

 

정식 출시 (서울 리전 포함)

CodeBuild 서비스 통합은 Step Functions 및 CodeBuild 서비스가 제공되는 모든 상업용 및 GovCloud 지역에서 사용할 수 있습니다(서울 리전 가능). 사용 가능한 리전 정보는  AWS 리전 표를 참고해 주십시오. 자세한 내용은 설명서를 참고 부탁드립니다.

AWS Serverless Hero Gojko Adzic로서 AWS 개발 운영 블로그CodeBuild는 관리 작업을 실행하는 데 사용할 수 있다고 밝혔습니다. Step Functions 와의 통합으로 새로운 가능성이 열렸습니다.

 

원문URL :  https://aws.amazon.com/ko/blogs/aws/new-building-a-continuous-integration-workflow-with-step-functions-and-aws-codebuild/

** 메가존 클라우드 TechBlog는 AWS BLOG 영문 게재 글 중에서 한국 사용자들에게 유용한 정보 및 콘텐츠를 우선적으로 번역하여 내부 엔지니어 검수를 받아서, 정기적으로 게재하고 있습니다. 추가로 번역 및 게재를 희망하는 글에 대해서 관리자에게 메일 또는 SNS 페이지에 댓글을 남겨주시면, 우선적으로 번역해서 전달해드리도록 하겠습니다.