Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .travis.yml_example
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
language: go

go:
- 1.8.3

env:
matrix:
- PACKAGE_TYPE=deb
- PACKAGE_TYPE=rpm

#install files needed for deployment
before_install:
- sudo apt-get -q update
- sudo apt-get install -y make rpm ruby-dev build-essential

#install fpm used for building packages
install:
- gem install fpm --no-document

#test the code
script:
- make test

#build the packages
after_success:
- make pkg/$PACKAGE_TYPE

deploy:
provider: s3
access_key_id:
secure: <travis encrypted id key>
secret_access_key:
secure: <travis encrypted access key>
bucket: <bucket name>
local-dir: ./pkg/$PACKAGE_TYPE
upload-dir: $PACKAGE_TYPE
acl: public_read
skip_cleanup: true
region: eu-central-1
47 changes: 47 additions & 0 deletions Makefile_example
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
NAME = pkgname
URL = https://InsertUrl.here
DESC = "description"
MAINTAINER = "Maintainer name"
LICENSE = "License here"
DEPENDENCIES = "" #Add dependencies here and add '-d $(DEPENDENCIES)' to fpm in pkg/% block

PKGDIR := ./pkg
VERSION ?= $(shell cat ./VERSION)
PACKAGE_TYPE := deb rpm

PATH_BIN ?= /usr/bin

test: vet ## runs unit tests
go test -v ./...

vet: ## examines the go code with `go vet`
go vet ./...

$(PKGDIR): $(addprefix $(PKGDIR)/,$(PACKAGE_TYPE)) ## creates artifacts for all distributions

# PACKAGING
$(PKGDIR)/rpm: TARGET_ARTIFACT=rpm
$(PKGDIR)/rpm: FPM_DEPENDENCIES=rpm
$(PKGDIR)/rpm: TARGET_FILE=$(NAME)-$(VERSION)-x86_64.rpm
$(PKGDIR)/deb: TARGET_ARTIFACT=deb
$(PKGDIR)/deb: FPM_DEPENDENCIES=apt
$(PKGDIR)/deb: TARGET_FILE=$(NAME)_$(VERSION)_amd64.deb
$(PKGDIR)/%: build ## creates the artifact for a specific distribution
mkdir -p $(PKGDIR)/$*
fpm -s dir -t $(TARGET_ARTIFACT) \
--name $(NAME) \
--package ./pkg/$*/$(TARGET_FILE) \
--category admin \
--deb-compression bzip2 \
--url $(URL) \
--description $(DESC) \
--maintainer $(MAINTAINER) \
--license $(LICENSE) \
--version $(VERSION) \
--architecture amd64 \
./usr

# BUILD
build: ## builds the code
mkdir -p .$(PATH_BIN)
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -a -o .$(PATH_BIN)/$(NAME)
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,15 @@
# lambdaRepos
POC for managing RPM and DEB repositories using aws' S3 and λ

# Info
Code for managing `yum`(rpm) repository is located in [rpm folder](https://github.com/tactycal/lambdaRepos/tree/master/rpm)

Code for managing `apt`(deb) repository is located in [deb folder](https://github.com/tactycal/lambdaRepos/tree/master/deb)

Both folders contain more detailed info on setting up S3 bucket and lambda function, that keeps your repo in sync with provided packages

## Combining with TravisCI

It is possible to automate deployment of packages by combining this repository with Travis CI.

Examples of `.travis.yml` and `Makefile` used for automatic deployment of go project can be found in repository
18 changes: 18 additions & 0 deletions deb/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
ZIPPED_FILES := s3apt.py requirements/gnupg.py # files to compress in root of zip
ZIPPED_DIR := debian # folders from /requirements to compress to root of zip

all: requires package

help: ## displays this message
@grep -E '^[a-zA-Z_/%\-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

requires: ## installs required packages
pip install -t ./requirements -r requirements.txt

package: ## creates zip of code
zip -j code.zip $(ZIPPED_FILES)
cd requirements && zip -r ../code.zip $(ZIPPED_DIR)

clean: ## cleans up the repository
/bin/rm -rf code.zip
/bin/rm -rf ./requirements
143 changes: 143 additions & 0 deletions deb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# AWS Lambda APT repository manager for S3

Rewrite of [szinck/s3apt](https://github.com/szinck/s3apt) with a few changes and extra features - Release file is being generated and is signed with GPG key provided

## Readme contents

* [Setting up code, S3 and Lambda](#setting-up-code-s3-and-lambda)
* [Getting the code](#getting-the-code)
* [GPG key](#gpg-key)
* [Environmental variables](#environmental-variables)
* [Set up role](#set-up-role)
* [Set up lambda with CLI](#set-up-lambda-with-cli)
* [Set up lambda manually](#set-up-lambda-manually)
* [The triggers](#the-triggers)
* [Set up S3](#set-up-s3)
* [Setting up apt](#setting-up-apt)
* [Notes](#notes)

## Setting up code, S3 and Lambda

### Getting the code
Clone the repo, get all other required files and compress them
```
git clone https://github.com/tactycal/lambdaRepos.git
cd lambdaRepos/deb
make all
```

### GPG key
create your gpg key (skip to exporting your key, if you already have it)
```
gpg --gen-key
# Follow the instructions
# Create 'RSA and RSA' key - option 1
# For maxium encryption it is recommended to make 4096 bits long key
# Key should not expire
```

export your key

```
gpg --export-secret-key -a "User Name" > secret.key # exports secret key to secret.key
```

### Set up role

Create new role with s3 write/read access

Here is a minimal requirement for the policy that is included in role:
```
{"Version": "2012-10-17",
"Statement": [
{"Sid": "<THIS IS UNIQUE>",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:PutObjectAcl"],
"Effect": "Allow",
"Resource": "arn:aws:s3:::<YOUR BUCKET NAME>/*"}]}
```

### Environmental variables
These are the environmental variables you will have to set:

| Key | Value |
| --- | ---|
| PUBLIC | True/False |
| GPG_KEY | File |
| GPG_PASS | GPG key password |
| BUCKET_NAME | Bucket Name |
| CACHE | Directory |

**PUBLIC** Set to `True` for the outputs to be publicly readable

**GPG_KEY** Location of your GPG private key from root of the bucket (e.g. secret/private.key). Not providing this variable will cause lambda to skip GPG singing

**GPG_PASS** Password of private key uploaded to GPG_KEY (Note: environmental variables are/can be encrypted using KMS keys)

**BUCKET_NAME** Name of the bucket. Should be the same as the one selected in triggers and the one you're using for repository

**CACHE** Path to folder for packages cache(e.g. deb/cache)

### Set up lambda with CLI

[Install aws cli](http://docs.aws.amazon.com/cli/latest/userguide/installing.html)

Create new lambda function:
```
aws lambda create-function \
--function-name <name the function> \
--zip-file fileb://code.zip \
--role <role's arn> \ # arn from role with S3 read/write access
--handler s3apt.lambda_handler \
--runtime python2.7 \
# Replace '<...>' with environmental variables
--environment Variables='{PUBLIC=<bool>, GPG_KEY=<file>, GPG_PASS=<password>, BUCKET_NAME=<bucket name>, CACHE=<dir>}'
```

### Set up lambda manually

If CLI is not your thing, then you can upload code manaully

Create new lambda function, set handler to **s3apt.lambda_handler**, runtime to **python 2.7**

Upload `code.zip` to lambda function

### The triggers

* Object Created(All), suffix 'deb'
* Object Removed(All), suffix 'deb'
* If you are using certain directory as a repo, set it as prefix

### Set up S3
Make folder in your S3 bucket with the same name as CACHE variable

Upload secret key file to location you specified as GPG_KEY


Upload .deb file to desired folder, lambda function should now keep your repository up to date

## Setting up apt

First time set up
```
sudo echo "deb https://s3.$AWS_SERVER.amazonaws.com/$BUCKET_NAME/$PATH_TO_FOLDER_WITH_DEBIAN_FILES /" >> /etc/apt/sources.list
#an example of link "https://s3.eu-central-1.amazonaws.com/testbucket/repo"
#add public key to trusted sources - you have to export public key or use key server
apt-key add <path to key>
sudo apt update
sudo apt install <packages>
```

Upgrading package
```
sudo apt update
sudo apt upgrade
```

## Notes

* .deb, Release and Package files are and should be publicly accessible for previously mentioned method of setting up apt's sources list to work, if you don't want them to be, then change PUBLIC in environment variables to False and refer to szinck's guide [here](http://webscale.plumbing/managing-apt-repos-in-s3-using-lambda)
* If somebody tries to inject a malicious deb file in your repo it will be automaticly added to repository. It is your job to make bucket secure enough for this not to happen.!!!
* **You should change lambda timeout to more than 10 seconds to make sure that function will work**
9 changes: 9 additions & 0 deletions deb/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
boto3==1.3.1
botocore==1.4.41
docutils==0.12
futures==3.0.5
jmespath==0.9.0
python-dateutil==2.5.3
python-debian==0.1.28
six==1.10.0
python-gnupg==0.4.1
Loading