2
votes

I'm trying to hook my GitHub repo with S3 so every time there's a commit, AWS CodePipeline will deploy the ./<path>/public folder to a specified S3 bucket.

So far in my pipeline, the Source works (hooked to GitHub and picks up new commits) but the Deploy failed because: Action execution failed BundleType must be either YAML or JSON.

This is how I set them up:

CodePipeline

  • Action name: Source
  • Action provider: GitHub
  • Repository: account/repo
  • Branch: master
  • GitHub webhooks

CodeDeploy

  • Compute type: AWS Lambda
  • Service role: myRole
  • Deployment settings: CodeDeployDefault.LambdaAllAtOnce

IAM Role: myRole

  • AWS Service
  • Choose the service that will use this role: Lambda / CodeDeploy
  • Select your use case: CodeDeploy
  • Policies: AWSCodeDeployRole

I understand that there must be a buildspec.yml file in the root folder. I've tried using a few files I could find but they don't seem to work. What did I do wrong or how should I edit the buildspec file to do what I want?

Update

Thanks to @Milan Cermak. I understand I need to do:

CodePipeline:

  • Stage 1: Source: hook with GitHub repo. This one is working.
  • Stage 2: Build: use CodeBuild to grab only the wanted folder using a buildspec.yml file in the root folder of the repo.
  • Stage 3: Deploy: use
Action Provider: S3
Input Artifacts: OutputArtifacts (result of stage 2).
Bucket: the bucket that hosts the static website.

CodePipeline works. However, the output contains only files (.html) not folders nested inside the public folder.

I've checked this and figured how to remove path of a nested folder with discard-paths: yes but I'm unable to get all the sub-folders inside the ./<path>/public folder. Any suggestion?

4

4 Answers

2
votes

You shouldn't use CodeDeploy, as that's a service for automation of deployments of applications, but rather CodeBuild, which executes commands and prepares the deployment artifact for further use in the pipeline.

These commands are in thebuildspec.yml file (typically in the root directory of the repo, but it's configurable). For your use case, it won't be too complicated, as you're not compiling anything or running tests, etc.

Try this as a starting point:

version: 0.2

phases:
  build:
    commands:
      - ls

artifacts:
  files:
    - public/*

The phases section is required, that's why it's included (at least, thanks to the ls command, you'll see what files are present in the CodeBuild environment), but it's not interesting for your case. What is interesting is the artifacts section. That's where you define what is the output of the CodeBuild phase, i.e. what gets passed further to the next step in the pipeline.

Depending on how you want to have the files structured (for example, do you want to have the public directory also in the artifact or do you only want to have the files themselves, without the parent dir), you might want to use other configuration that's possible in the artifacts section. See the buildspec reference for details.

Remember to use the output artifact of the CodeBuild step as the input artifact of the Deploy to S3 step.

3
votes

CodeBuild use buildspec, but CodeDeploy use appspec.

Is there any appspec file?

1
votes

Buildspec is for CodeBuild as t_yamo pointed out.

You are using CodeDeploy which uses an appspec.yml file, which looks something like this for my config.

version: 0.0
os: linux
files:
  - source: /
    destination: /path/to/destination
hooks:
  BeforeInstall:
    - location: /UnzipResourceBundle.sh
  ApplicationStart:
    - location: /RestartServer.sh
      timeout: 3600

UnzipResourceBundle.sh is just a bash script which can be used to do any number of things.

#!/bin/bash
// Do something

You can find a sample for the AppSpec.yml file from Amazon Documentation here - https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-example.html#appspec-file-example-lambda