CodeBuild extract in to folder in S3 bucket - amazon-web-services

I've been trying to navigate the CodeBuild docs to find an answer without any success.
I have a pipeline that pulls from github on commit and builds and deploys to S3. However, it takes the dist directory and just replaces anything currently in the bucket.
I wish to edit my buildspec to deploy to S3 in a folder named after the commit ID. Meaning CODEBUILD_RESOLVED_SOURCE_VERSION/...
Is there a way to do this in the buildspec.yml?
I want to keep a history of old builds in case I need to revert to an older.

Figured it out.
In the deployment stage of CodePipeline, add #{SourceVariables.CommitId} to the deployment path option.

Related

How to change CodePipeline artifacts behavior? (If possible)

I am designing a CI/CD system and looking for complete isolation between frontend and backend components. They will use separate CodeCommit Repositories, CodeBuild Projects, and deployment mechanisms. I've even created separate S3 buckets to house the artifacts. Furthermore, I'm using lengthy descriptive names for the pipelines, and related services, to ensure there's no confusion.
However, I am hitting an annoying issue where CodePipeline seems to be creating a Folder inside my artifacts S3 bucket with a truncated version of the pipeline name. I feel this is irrelevant and will only add to the confusion I'm trying to avoid. The entire S3 bucket is dedicated to those pipeline artifacts so I don't want a Folder containing everything within. I don't see anyway to stop CodePipeline from behaving this way.
Example:
Pipeline Name: my-clients-pipeline-for-frontend
S3 Artifacts: my-clients-pipeline-artifacts-for-frontend
----> my-clients-pipeline-f
--------> SourceArtifact
--------> BuildAritfact
Pipeline Name: my-clients-pipeline-for-backend
S3 Artifacts: my-clients-pipeline-artifacts-for-backend
----> my-clients-pipeline-f
--------> SourceArtifact
--------> BuildAritfact
The documentation states,
"Every time you use the console to create another pipeline in that
Region, CodePipeline creates a folder for that pipeline in the bucket.
It uses that folder to store artifacts for your pipeline as the
automated release process runs."
Although, I am using CloudFormation to build the pipelines and not sure if this still applies. The pipelines are working... can I remove this truncated folder somehow?
https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome-introducing-artifacts.html
This response is 19 months late so I hope you were able to find a solution in the meantime. ^-^
I generally try and use aws CLI for anything related to AWS Env modification when my pipelines are running. So for example in your case, if you have manually set your output artifacts to go in the buckets with appropriate names i.e: "my-clients-pipeline-artifacts-for-backend", then you can add a stage after deploy stage to call AWS Lambda that uses aws CLI to remove any folders created by AWS CodePipeline for example:
aws s3 rm s3://my-clients-pipeline-for-backend/my-clients-pipeline-f
--recursive
This command recursively deletes everything in the folder: "my-clients-pipeline-f" and then deletes the folder itself as well.
I know this isn't a super straightforward approach but it is a workaround/solution that works for me in most cases. I have not tested this to delete build artifact s3 folders but it should work fine nonetheless.
REFERENCES
Integrate AWS CLI in Lambda: https://bezdelev.com/hacking/aws-cli-inside-lambda-layer-aws-s3-sync/
Invoke Lambda in CodePipeline: https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html#actions-invoke-lambda-function-add-action

Is it possible to rename or change the directory of the AWS codedeploy appspec file?

I've set up my codedeploy appspec.yml file currently located in my root folder. I have a CI/CD that runs 2 pipelines depending on which branch the new code is pushed/merged into. I have one for production and one for staging. Previously i've used the s3 artifacts from the staging to build the production but i want to change it so it runs the production pipeline and deploys when i push to master. The issue is that in order to build it i have some hooks running bash scripts where the content is different from the staging appspec file.
Any ideas on how it is possible to have multiple appspec files for aws codedeploy?
BR Lukas
You can't rename artifacts on the fly. You can do it in an intermediate step before invoking CodeDeploy. BTW, you say you are building different versions for different environments, a better approach would be to user either instance / user metadata or tags.

CodeDeploy to S3

I have a site in a S3 bucket, configured for web access, for which I run an aws s3 sync command every time I push on a specific git repository (I'm using Gitlab at the moment).
So if I push to stable branch, a Gitlab runner performs the npm start build command for building the site, and then aws s3 sync to synchronize to a specific bucket.
I want to migrate to CodeCommit and use pure AWS tools to do the same.
So far I was able to successfully setup the repository, create a CodeBuild for building the artifact, and the artifact is being stored (not deployed) to a S3 bucket. Difference is that I can't get it to deploy to the root folder of the bucket instead of a subfolder, seems like the process is not made for that. I need it to be on a root folder because of how the web access is configured.
For the deployment process, I was taking a look at CodeDeploy but it doesn't actually let me deploy to S3 bucket, it only uses the bucket as an intermediary for deployment to a EC2 instance. So far I get the feeling CodeDeploy is useful only for deployments involving EC2.
This tutorial with a similar requirement to mine, uses CodePipeline and CodeBuild, but the deployment step is actually a aws s3 sync command (same as I was doing on Gitlab), and the actual deployment step on CodePipeline is disabled.
I was looking into a solution which involves using AWS features made for this specific purpose, but I can't find any.
I'm also aware of LambCI, but to me looks like what CodePipeline / CodeBuild is doing, storing artifacts (not deploying to the root folder of the bucket). Plus, I'm looking for an option which doesn't require me to learn or deploy new configuration files (outside AWS config files).
Is this possible with the current state of AWS features?
Today AWS has announced as a new feature the ability to target S3 in the deployment stage of CodePipeline. The announcement is here, and the documentation contains a tutorial available here.
Using your CodeBuild/CodePipeline approach, you should now be able to choose S3 as the deployment provider in the deployment stage rather than performing the sync in your build script. To configure the phase, you provide an S3 bucket name, specify whether to extract the contents of the artifact zip, and if so provide an optional path for the extraction. This should allow you to deploy your content directly to the root of a bucket by omitting the path.
I was dealing with similar issue and as far as I was able to find out, there is no service which is suitable for deploying app to S3.
AWS CodeDeploy is indeed for deploying code running as server.
My solution was to use CodePipeline with three stages:
Source which takes source code from AWS CodeCommit
Build with AWS CodeBuild
Custom lambda function which after successful build takes artifact from S3 artifact storage, unzip it and copies files to my S3 website host.
I used this AWS lambda function from SeamusJ https://github.com/SeamusJ/deploy-build-to-s3
Several changes had to be made, I used node-unzip-2 instead of unzip-stream for unziping artifict from s3.
Also I had to change ACLs in website.ts file
Uploading from CodeBuild is currently the best solution available.
There's some suggestions on how to orchestrate this deployment via CodePipeline in this answer.

How to integrate a GIT webhook with AWS CodePipeline?

Can give me some input on configuring AWS CodePipeline to trigger a ZipDownload or a Git pull if the developer commits a code into the Git branch ? I'm new to AWS CodePipeline and AWS Lamba.
For CodePipeline to subscribe to a GitHub repo (using the console):
Create a Source Action of "GitHub", and choose your Repo. Choose an Output artifact name that you will remember for the next step. Under advanced, select "Run pipeline when changes in source content are detected".
Create a Build Action using the build provider of your choice. Choose the Input artifact name you chose in step #1.
When a change occurs in the GitHub repo, CodePipeline will execute the Source action, which will build a zip of the repo as is, and put it in an S3 bucket as an Output artifact. It will then pass this file's S3 name into the Build action (using the variable name given in the steps above), so that the zip file can be downloaded and built.
If you have a working buildspec.yml in the root of the repo, you can use the AWS CodeBuild provider, and the artifacts will be copied to the output bucket when done.
CodePipeline is supposed to manage automation from source code to final deployment, which embrace the concept of continuous integration. Though how to use CodePipeline depends on use case, CodePipeline does source code download for you by detecting source change. Which means what you should thinking about is what to do next after pushing the code, such as run a build action or test action.
It's worth to follow the tutorial to build a pipeline and learn how it works: Tutorial: Create a Simple Pipeline (AWS CodeCommit Repository). It may only take half an hour.
Though it's using codecommit, but it works similar as github. For integration with GitHub, there is a blog you may found useful: Integrating Git with AWS CodePipeline

AWS CodePipeline adding artifacts to S3 in less useful format than running steps individually

I've set up a CodePipeline with the end goal of having a core service reside on S3 as a private maven repo for other pipelines to rely on. When the core service is updated and pushed to AWS CodeCommit, the pipeline should run, test it, build a jar using a maven docker image, then push the resulting jar to S3 where it can be accessed by other applications as needed.
Unfortunately, while the CodeBuild service works exactly how I want it to, uploading XYZCore.jar to /release on the bucket, the automated pipeline itself does not. Instead, it uploads to a "XYZCorePipeline" folder, which contains the input and output artifacts of the build. The output artifact itself is a zip file that's just a random string of characters. I checked the pipeline and it's using the service correctly, but pipeline specific builds always output there while standalone builds of the CodeBuild service output how I'd like them, allowing me to take advantage of things like versioning. What's the best way for me to fix the settings so the two builds match?
Unfortunately CodePipeline does not support this use case.
As a workaround you could upload the artifact to S3 by invoking AWS CLI (aws s3 cp ...) from your buildspec.yml post_build.