diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5521923..8264fd6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,4 +26,27 @@ jobs: - name: Run unit tests run: | - pytest project-d-serverless-api/tests/ -v \ No newline at end of file + pytest project-d-serverless-api/tests/ -v + + deploy: + name: Trigger CodeBuild + runs-on: ubuntu-latest + needs: test + if: github.ref == 'refs/heads/main' && github.event_name == 'push' + + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ap-northeast-1 + + - name: Trigger CodeBuild + run: | + BUILD_ID=$(aws codebuild start-build \ + --project-name project-d-build \ + --source-version main \ + --query 'build.id' \ + --output text) + echo "Started CodeBuild: $BUILD_ID" \ No newline at end of file diff --git a/appspec.yml b/appspec.yml new file mode 100644 index 0000000..9dcdab2 --- /dev/null +++ b/appspec.yml @@ -0,0 +1,10 @@ +version: 0.0 +Resources: + - myLambdaFunction: + Type: AWS::Lambda::Function + Properties: + Name: "project-d-api" + Alias: "live" + CurrentVersion: "" + TargetVersion: "" +Hooks: [] \ No newline at end of file diff --git a/buildspec.yml b/buildspec.yml new file mode 100644 index 0000000..f8fc9ba --- /dev/null +++ b/buildspec.yml @@ -0,0 +1,50 @@ +version: 0.2 + +phases: + install: + runtime-versions: + python: 3.11 + commands: + - pip install pytest boto3 moto + + build: + commands: + - echo "Running unit tests..." + - cd project-d-serverless-api + - python -m pytest tests/ -v + - cd .. + + post_build: + commands: + - echo "Publishing new Lambda version..." + - aws lambda publish-version --function-name project-d-api --query 'Version' --output text > /tmp/new_version.txt + - NEW_VERSION=$(cat /tmp/new_version.txt) + - echo "New version is $NEW_VERSION" + - CURRENT_VERSION=$(aws lambda list-aliases --function-name project-d-api --query 'Aliases[?Name==`live`].FunctionVersion' --output text) + - echo "Current version is $CURRENT_VERSION" + - sed -i "s//$CURRENT_VERSION/g" appspec.yml + - sed -i "s//$NEW_VERSION/g" appspec.yml + - | + python3 -c " + import json, subprocess + with open('appspec.yml') as f: + content = f.read() + revision = { + 'revisionType': 'AppSpecContent', + 'appSpecContent': {'content': content} + } + cmd = ['aws', 'deploy', 'create-deployment', + '--application-name', 'project-d-deploy', + '--deployment-group-name', 'project-d-deployment-group', + '--revision', json.dumps(revision)] + result = subprocess.run(cmd, capture_output=True, text=True) + print(result.stdout) + print(result.stderr) + exit(result.returncode) + " + +artifacts: + files: + - appspec.yml + - project-d-serverless-api/lambda/index.py + discard-paths: no \ No newline at end of file diff --git a/project-d-serverless-api/codebuild.tf b/project-d-serverless-api/codebuild.tf new file mode 100644 index 0000000..cf03937 --- /dev/null +++ b/project-d-serverless-api/codebuild.tf @@ -0,0 +1,87 @@ +# CodeBuild用IAMロール +resource "aws_iam_role" "codebuild_role" { + name = "codebuild-project-d-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [{ + Effect = "Allow" + Principal = { Service = "codebuild.amazonaws.com" } + Action = "sts:AssumeRole" + }] + }) +} + +resource "aws_iam_role_policy" "codebuild_policy" { + role = aws_iam_role.codebuild_role.name + + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Effect = "Allow" + Action = [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ] + Resource = "*" + }, + { + Effect = "Allow" + Action = [ + "s3:GetObject", + "s3:PutObject", + "s3:GetBucketAcl", + "s3:GetBucketLocation" + ] + Resource = "*" + }, + { + Effect = "Allow" + Action = [ + "lambda:PublishVersion", + "lambda:ListAliases", + "lambda:GetAlias", + "lambda:UpdateAlias", + "codedeploy:CreateDeployment", + "codedeploy:GetDeployment", + "codedeploy:GetDeploymentConfig", + "codedeploy:RegisterApplicationRevision", + "codedeploy:GetApplicationRevision" + ] + Resource = "*" + } + ] + }) +} + +# CodeBuildプロジェクト +resource "aws_codebuild_project" "project_d" { + name = "project-d-build" + description = "CI build and test for Project D serverless API" + service_role = aws_iam_role.codebuild_role.arn + build_timeout = 10 + source_version = "e-phase2-codebuild-deploy" + + source { + type = "GITHUB" + location = "https://github.com/RG756/cloud-engineering-learning" + buildspec = "buildspec.yml" + git_clone_depth = 1 + + git_submodules_config { + fetch_submodules = false + } + } + + environment { + compute_type = "BUILD_GENERAL1_SMALL" + image = "aws/codebuild/standard:7.0" + type = "LINUX_CONTAINER" + } + + artifacts { + type = "NO_ARTIFACTS" + } +} \ No newline at end of file diff --git a/project-d-serverless-api/codedeploy.tf b/project-d-serverless-api/codedeploy.tf new file mode 100644 index 0000000..d952ff1 --- /dev/null +++ b/project-d-serverless-api/codedeploy.tf @@ -0,0 +1,37 @@ +# CodeDeploy用IAMロール +resource "aws_iam_role" "codedeploy_role" { + name = "codedeploy-project-d-role" + + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [{ + Effect = "Allow" + Principal = { Service = "codedeploy.amazonaws.com" } + Action = "sts:AssumeRole" + }] + }) +} + +resource "aws_iam_role_policy_attachment" "codedeploy_policy" { + role = aws_iam_role.codedeploy_role.name + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSCodeDeployRoleForLambda" +} + +# CodeDeployアプリケーション +resource "aws_codedeploy_app" "project_d" { + name = "project-d-deploy" + compute_platform = "Lambda" +} + +# CodeDeployデプロイグループ +resource "aws_codedeploy_deployment_group" "project_d" { + app_name = aws_codedeploy_app.project_d.name + deployment_group_name = "project-d-deployment-group" + service_role_arn = aws_iam_role.codedeploy_role.arn + deployment_config_name = "CodeDeployDefault.LambdaAllAtOnce" + + deployment_style { + deployment_option = "WITH_TRAFFIC_CONTROL" + deployment_type = "BLUE_GREEN" + } +} \ No newline at end of file