Uploading to an S3 bucket from bitbucket pipelines
10 Apr 2018
I was recently writing a build script that should get triggered whenever I push my code to Bitbucket using the pipelines feature, see Bitbucket Pipelines. Basically you create a yaml file with tasks. Each time you push code, Bitbucket spins up a linux docker container to run these tasks one after another. In my case the task was simple - I just had to package my powershell scripts into a zip file and upload it to my AWS S3 bucket.
Pre-Reqs:
To upload files to S3, first create a user account and set the type of access to allow
“Programmatic access”, see this. You should also set permissions to ensure that the user has access to the bucket. Make sure you set this up first.
Create a pipeline using steps in this link. This will create a bitbucket-pipelines.yml file in the root of your repository. Note that you cannot use tabs, you have to indent using spaces. You should use the bitbucket’s interface when possible, because it warns you when you have \t characters in the yaml file.
Yaml file
You can write line comments using “#”. The first real line in the yaml file specifies the docker image you want to use. In my case I used the standard Python 3.5.1 image, so I have “image: python:3.5.1” as the image.
Bitbucket allows you to create a default pipeline, or seperate pipelines for each of your branches (patterns). There are predefined sections for “pipelines”, “branches”, “step” that Bitbucket pipelines understand. I just wanted one for my master branch and one for my dev branch - so I used the following template. “master” refers to the master branch in my repository and “devbranch” refers to my development branch. We would be using the Amazon provided boto3 package to perform upload, so one of the steps in your yaml will be to use pip to install the package. You can cache pip, so that your image already has it and doesn’t have to download it each time you run the pipeline.
I prefer to keep my build scripts and python requirements file it in a build folder in my repository. So the first step is to cd to this folder and then call pip to install the requirements. The requirements.txt file just has this one line for now:
The steps to be performed are:
echo “Build started”
cd .\build
pip install -r requirements.txt
python ./BuildScript.py package_name
echo “Build complete”
Here’s my completed bitbucket-pipelines.yml file.
Now for the actual Python script, thats pretty straight forward. You import boto3, create an instance of boto3.resource for the s3 service. Call the upload_file method and pass the file name.
In the below example:
“src_files” is an array of files that I need to package.
“package_name” is the package name.
“bucket_name” is the S3 bucket name that I want to upload to.
“my_aws_access_key_id” and “my_aws_secret_access_key” are the access keys, I have hard coded theses just as an example. I would strongly advice you against doing that, especially if your repository is not a private one.
ZipDirectory is a function that wraps around shutil.make_archive to create the package.
CreateZipPackageAndUpload is a function that copies the file to a temporary folder, zips the folder and uploads to the S3 bucket.