# 如何用 AWS CodePipeline 建立自動部署 AWS Lambda [TOC] ###### tags: `chatgpt` --- 以下是使用 AWS CodePipeline 建立自動部署 AWS Lambda 的步驟: 1. 在 AWS Console 中建立一個 CodePipeline 流程。您可以在 CodePipeline 服務中建立新的 pipeline。 2. 在 pipeline 的設定中,選擇 GitHub 作為 source provider,並選擇要自動部署的 repository。 3. 設定 pipeline 的建構和測試步驟。您可以使用 AWS CodeBuild 服務來建構和測試您的 Lambda 函數。 4. 設定 pipeline 的部署步驟。在這裡,您可以使用 AWS CloudFormation 服務來自動部署 Lambda 函數。您可以建立一個 CloudFormation Stack,並在 stack 中定義您的 Lambda 函數和相關的 AWS 資源,如 IAM 角色和 S3 存儲桶。 5. 測試部署。當您建立完 pipeline 後,您可以推送程式碼到 repository,並觀察 CodePipeline 的流程是否自動觸發了建構、測試和部署步驟。如果所有步驟都成功,您的 Lambda 函數就會自動部署。 總結來說,您需要設定 CodePipeline 的 `source`、`build`、`test` 和 `deploy` 步驟,並使用 AWS CodeBuild 和 AWS CloudFormation 服務來自動化 Lambda 函數的建構和部署。透過這樣的流程,您可以更輕鬆地自動化部署 Lambda 函數,讓您可以更快地交付代碼並減少錯誤。 ## 我打算使用 docker 佈建 AWS Lambda 函數,給我一個 buildspec 範例 以下是一個範例 `buildspec.yml` 檔案,您可以使用這個檔案來建立 Docker 映像檔,然後將其上傳到 AWS ECR 存儲庫中,最後使用 AWS CodeBuild 建立 Lambda 函數並部署到 AWS Lambda: ```yaml version: 0.2 phases: pre_build: commands: - echo Logging in to Amazon ECR... - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7) - IMAGE_TAG=${COMMIT_HASH:=latest} build: commands: - echo Build started on `date` - echo Building the Docker image... - docker build -t $REPOSITORY_URI:$IMAGE_TAG . - docker tag $REPOSITORY_URI:$IMAGE_TAG $REPOSITORY_URI:latest post_build: commands: - echo Build completed on `date` - echo Pushing the Docker images to the ECR repository... - docker push $REPOSITORY_URI:$IMAGE_TAG - docker push $REPOSITORY_URI:latest - echo Writing image definitions file... - printf '[{"name":"%s","imageUri":"%s"}]' $IMAGE_REPO_NAME $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json artifacts: files: imageDetail.json ``` 這個範例 `buildspec.yml` 檔案有三個階段(phases):`pre_build`、`build` 和 `post_build`。在 `pre_build` 階段,我們定義了一些變數,例如` $AWS_ACCOUNT_ID` 和 `$IMAGE_REPO_NAME`,它們會在後續階段中使用。接下來,我們登錄到 AWS ECR 存儲庫中,以便能夠將 Docker 映像檔上傳到存儲庫中。 在 `build` 階段,我們使用 `docker build` 命令來建立 Docker 映像檔。在 `post_build` 階段,我們將 Docker 映像檔推送到 AWS ECR 存儲庫中,並創建一個包含 Lambda 函數資訊的 `imageDetail.json` 檔案,以便在 CodePipeline 的部署階段中使用。 使用這個 `buildspec.yml` 檔案,您可以使用 AWS CodeBuild 服務來建立 Docker 映像檔,並將其上傳到 AWS ECR 存儲庫中,這樣您就可以使用 AWS CodePipeline 服務來自動部署 AWS Lambda 函數了。 ## 能將範例改成適用 aws-serverless-java-container-springboot2 的樣子嗎 當使用 `aws-serverless-java-container-springboot2` 庫時,您需要在 Docker 映像檔中打包 Spring Boot 應用程式和 Java 运行时环境,并将其部署到 AWS Lambda 中。下面是一個範例 `buildspec.yml` 檔案,可用於構建 AWS Lambda Docker 映像檔,並將其部署到 AWS Lambda 中: ```yaml version: 0.2 phases: pre_build: commands: - echo Logging in to Amazon ECR... - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7) - IMAGE_TAG=${COMMIT_HASH:=latest} build: commands: - echo Build started on `date` - echo Building the Docker image... - mvn -B clean package - docker build -t $REPOSITORY_URI:$IMAGE_TAG -f Dockerfile . - docker tag $REPOSITORY_URI:$IMAGE_TAG $REPOSITORY_URI:latest post_build: commands: - echo Build completed on `date` - echo Pushing the Docker images to the ECR repository... - docker push $REPOSITORY_URI:$IMAGE_TAG - docker push $REPOSITORY_URI:latest - echo Updating the AWS Lambda function... - aws lambda update-function-code --function-name $LAMBDA_FUNCTION_NAME --image-uri $REPOSITORY_URI:$IMAGE_TAG artifacts: files: - target/*.jar ``` 這個範例 `buildspec.yml` 檔案中的 `pre_build` 階段與之前的範例類似,我們還是先登錄到 AWS ECR 存儲庫中,然後設定變數以便後續階段使用。 在 `build` 階段,我們使用 Maven 構建 Spring Boot 應用程式,然後使用 `Dockerfile` 檔案來建立 Docker 映像檔。您可以將 `Dockerfile` 檔案放在您的項目根目錄中,然後在 `build` 階段中使用 `-f` 參數來引用它。 在 `post_build` 階段,我們將 Docker 映像檔推送到 AWS ECR 存儲庫中,然後使用 aws lambda update-function-code 命令將 Docker 映像檔部署到 AWS Lambda 中。最後,我們通過將應用程式的 JAR 檔案包含在 `artifacts` 中,來建立用於 CodePipeline 的發行物(artifacts)。 請注意,這個範例假設您已經設定了 `$LAMBDA_FUNCTION_NAME` 變數,這是您要部署 Docker 映像檔的 Lambda 函數名稱。如果您還沒有設定, ## 能將範例改成適用 aws-serverless-java-container-springboot2 的樣子嗎 當然,以下是使用 `aws-serverless-java-container-springboot2` 套件建立 Docker 映像檔的範例 buildspec.yml 檔案: ```yaml version: 0.2 env: variables: IMAGE_REPO_NAME: my-serverless-app DOCKERFILE_PATH: Dockerfile AWS_DEFAULT_REGION: us-east-1 phases: pre_build: commands: - echo Logging in to Amazon ECR... - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com - export TAG="$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)" build: commands: - echo Build started on `date` - echo Building the Docker image... - docker build -t $IMAGE_REPO_NAME:$TAG -f $DOCKERFILE_PATH . post_build: commands: - echo Build completed on `date` - echo Pushing the Docker image to the ECR repository... - docker tag $IMAGE_REPO_NAME:$TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$TAG - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$TAG artifacts: files: - '**/*' discard-paths: yes ``` 這個範例 `buildspec.yml` 檔案同樣有三個階段:`pre_build`、`build` 和 `post_build`。在 `pre_build` 階段中,我們登錄到 AWS ECR 存儲庫中,並定義了一些變數,例如 `$TAG`,它會在後續階段中使用。 在 `build` 階段中,我們使用 `docker build` 命令建立 Docker 映像檔。注意,這個範例中沒有使用 `-t $REPOSITORY_URI:$IMAGE_TAG` 命令,因為使用 `aws-serverless-java-container-springboot2` 套件時,Docker 映像檔的名稱和版本已經在 `Dockerfile` 中設置好了。 在 `post_build` 階段中,我們將 Docker 映像檔標記為對應的版本號,然後將它推送到 AWS ECR 存儲庫中。 使用這個 `buildspec.yml` 檔案,您可以建立 Docker 映像檔,並將它上傳到 AWS ECR 存儲庫中。然後,您可以使用 AWS CodePipeline 服務來自動部署 AWS Lambda 函數。注意,您需要在 AWS Lambda 函數的設定中使用適當的 Docker 映像檔名稱和版本。