Skip to content
This repository has been archived by the owner on Jul 19, 2023. It is now read-only.

update to Sceptre 2 #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

* **Nikolai Zujev** - *Initial work* - [jaymecd](https://github.com/jaymecd)
* **Jan Gazda** - *Py3 and other advices* - [1oglop1](https://github.com/1oglop1)
* **Alessandra Bilardi** - *Sceptre 2 updates* - [bilardi](https://github.com/bilardi)
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v1.0.0 - 2020-08-28

* Update Makefile, README.md, requirements.txt, configuration files, hook and resolver to Sceptre 2

## v0.1.2 - 2019-02-05

* Update examples dependency versions
Expand Down
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,18 @@ help:
## Install dependencies for this project
deps: clean
pip install -r requirements.txt
for dir in ./hooks/*; do (cd "$$dir" && pip install .); done
for dir in ./resolvers/*; do (cd "$$dir" && pip install .); done

## Copy plugins file to TARGET= sceptre project
plugins:
ifeq (, $(TARGET))
$(error Please specity TARGET= value)
$(error Please specify TARGET= value)
endif
/bin/test -d "$(TARGET)/hooks" || mkdir -p "$(TARGET)/hooks"
/bin/test -d "$(TARGET)/resolvers" || mkdir -p "$(TARGET)/resolvers"
/bin/cp -f hooks/s3_package.py "$(TARGET)/hooks/"
/bin/cp -f resolvers/s3_version.py "$(TARGET)/resolvers/"
/bin/cp -rf hooks/s3_package "$(TARGET)/hooks/"
/bin/cp -rf resolvers/s3_version "$(TARGET)/resolvers/"

## Clean temporary artifacts
clean:
Expand Down
45 changes: 30 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Sceptre zip-code-s3

Hook and resolver for [Sceptre](https://sceptre.cloudreach.com/latest/) `v1.3.4+` to package complex Lambda functions on-the-fly and deploy them using S3 bucket.
Hook and resolver for [Sceptre](https://sceptre.cloudreach.com/latest/) to package complex Lambda functions on-the-fly and deploy them using S3 bucket.

This solution, fully compatible with **Python 2/3**, works well for **ALL** AWS Lambda runtimes: just tune `Makefile` with your own instructions for concrete runtime.

Expand All @@ -20,7 +20,7 @@ Therefore, such archived artifacts should never be checked in, rather packaged a

### How To install

`NB!` _Sceptre `1.x` does not yet recognize `entry_points` installation option from `pip` setup manifesto._
`NB!` _Sceptre does not yet recognize `entry_points` installation option from `pip` setup manifesto._
_Therefore, it's not possible to install it using `pip`_.

* Clone the repository locally:
Expand All @@ -29,6 +29,20 @@ _Therefore, it's not possible to install it using `pip`_.
$ git clone git@github.com:cloudreach/sceptre-zip-code-s3.git
```

_If you want Makefile, configuration, hook, resolver and README.md compatible with Sceptre version from `1.3.4` to `1.5.0`_, run also

```bash
$ cd sceptre-zip-code-s3.git
$ git checkout tags/v0.1.2 -b sceptre-until-1.5.0
```

And _if you want Makefile, configuration, hook, resolver and README.md compatible with Sceptre version from `2.1.2`_, run also

```bash
$ cd sceptre-zip-code-s3.git
$ git checkout master
```

* Install required dependencies:

```bash
Expand Down Expand Up @@ -58,7 +72,7 @@ To display available commands, run `make` or `make help` command.
* Create new `S3` bucket for artifacts deployments:

```bash
$ sceptre launch-env example/storage
$ sceptre launch example/storage
```

`NB!` _It's possible to refer existing bucket, with enabled **Versioning** support._
Expand All @@ -68,15 +82,15 @@ To display available commands, run `make` or `make help` command.
* Deploy whole environment at once:

```bash
$ sceptre launch-env example/serverless
$ sceptre launch example/serverless
```

* Or deploy stacks one by one:

```bash
$ sceptre launch-stack example/serverless lambda-role
$ sceptre launch-stack example/serverless lambda-py2-deps
$ sceptre launch-stack example/serverless lambda-py3-deps-custom
$ sceptre launch example/serverless/lambda-role
$ sceptre launch example/serverless/lambda-py2-deps
$ sceptre launch example/serverless/lambda-py3-deps-custom
```

This is what have been done (per function):
Expand All @@ -92,9 +106,10 @@ This is what have been done (per function):
Find generated function name and region:

```bash
$ LAMBDA=( $(sceptre describe-stack-outputs example/serverless lambda-py2-deps \
$ LAMBDA=( $(sceptre --output json list outputs example/serverless/lambda-py2-deps.yaml \
| grep ':lambda:' \
| awk -F: '{print $NF, $5}') )
| awk -F: '{print $NF, $5}' \
| sed 's/"//') )
```

And then invoke function with JSON payload and parse result file:
Expand Down Expand Up @@ -125,13 +140,13 @@ key3:
* Do not forget to cleanup infrastructure after testing:

```bash
$ sceptre delete-env example/serverless
$ sceptre delete example/serverless
```

* If new S3 bucket was created during the test:

```bash
$ sceptre delete-env example/storage
$ sceptre delete example/storage
```

If it errors with `You must delete all versions in the bucket`, then:
Expand All @@ -141,7 +156,7 @@ key3:

$ python -c "import boto3; boto3.resource('s3').Bucket('${MY_BUCKET}').object_versions.delete()"

$ sceptre delete-env example/storage
$ sceptre delete example/storage
```

## Under the hood
Expand Down Expand Up @@ -204,8 +219,8 @@ As hook definition, resolver also has **auto-discovery** and **direct** modes.
```yaml
sceptre_user_data:
Code:
S3Bucket: !stack_output my-other-stack::BucketName
S3Key: !stack_output my-other-stack::KeyName
S3Bucket: !stack_output path-without-config/my-other-stack.yaml::BucketName
S3Key: !stack_output path-without-config/my-other-stack.yaml::KeyName
S3ObjectVersion: !s3_version
```

Expand Down Expand Up @@ -281,7 +296,7 @@ In other use-cases hook will upload archive every time it's called, as content M

#### Caveats

- note that Sceptre `v1.3.4` was tested only and it may misbehave on previous versions.
- note that this package was tested with Sceptre `v1.3.4`, `v1.5.0`, `v2.1.2` and `v2.3.0` and it may misbehave on previous versions.
- when running `Sceptre` from OSX, some packages may contain binary inside, so be sure to upload the proper one.
- custom encryption might require custom MD5/ETag lookup solution, see [S3 encryption](#s3-encryption)

Expand Down
8 changes: 4 additions & 4 deletions config/example/serverless/lambda-py2-deps.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
template_path: templates/example/lambda_function.py
template_path: example/lambda_function.py
hooks:
before_create:
- !s3_package src/example/lambda-py2-deps
before_update:
- !s3_package src/example/lambda-py2-deps
parameters:
Name: {{ environment_config.resource_prefix }}-py2-deps
Role: !stack_output lambda-role::Arn
Name: {{ resource_prefix }}-py2-deps
Role: !stack_output example/serverless/lambda-role.yaml::Arn
sceptre_user_data:
Runtime: python2.7
Handler: index.handler
Code:
S3Bucket: {{ environment_config.artifacts_bucket }}
S3Bucket: {{ artifacts_bucket }}
S3Key: lambda/example-py2-deps.zip
S3ObjectVersion: !s3_version
14 changes: 7 additions & 7 deletions config/example/serverless/lambda-py3-deps-custom.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
template_path: templates/example/lambda_function_custom.py
template_path: example/lambda_function_custom.py
hooks:
before_create:
- !s3_package src/example/lambda-py3-deps^^{{ environment_config.artifacts_bucket }}/lambda/example-py3-deps.zip
- !s3_package src/example/lambda-py3-deps^^{{ artifacts_bucket }}/lambda/example-py3-deps.zip
before_update:
- !s3_package src/example/lambda-py3-deps^^{{ environment_config.artifacts_bucket }}/lambda/example-py3-deps.zip
- !s3_package src/example/lambda-py3-deps^^{{ artifacts_bucket }}/lambda/example-py3-deps.zip
parameters:
Name: {{ environment_config.resource_prefix }}-py3-deps
Role: !stack_output lambda-role::Arn
Name: {{ resource_prefix }}-py3-deps
Role: !stack_output example/serverless/lambda-role.yaml::Arn
sceptre_user_data:
Runtime: python3.6
Handler: index.handler
S3_Bucket: {{ environment_config.artifacts_bucket }}
S3_Bucket: {{ artifacts_bucket }}
S3_Key: lambda/example-py3-deps.zip
S3_Version: !s3_version {{ environment_config.artifacts_bucket }}/lambda/example-py3-deps.zip
S3_Version: !s3_version {{ artifacts_bucket }}/lambda/example-py3-deps.zip
4 changes: 2 additions & 2 deletions config/example/serverless/lambda-role.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
template_path: templates/example/iam_role.py
template_path: example/iam_role.py
parameters:
Name: {{ environment_config.resource_prefix }}-lambda-role
Name: {{ resource_prefix }}-lambda-role
sceptre_user_data:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Expand Down
4 changes: 2 additions & 2 deletions config/example/storage/bucket-artifacts.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
template_path: templates/example/s3_bucket.yaml
template_path: example/s3_bucket.yaml
parameters:
BucketName: {{ environment_config.artifacts_bucket }}
BucketName: {{ artifacts_bucket }}
8 changes: 4 additions & 4 deletions hooks/s3_package.py → hooks/s3_package/s3_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ def run(self):
self.logger.debug(
"[{}] S3 bucket/key parsed from the argument".format(self.NAME)
)
elif "sceptre_user_data" in self.stack_config:
code = self.stack_config.get("sceptre_user_data").get("Code", {})
elif self.stack.sceptre_user_data and "Code" in self.stack.sceptre_user_data:
code = self.stack.sceptre_user_data.get("Code", {})
fn_root_dir, s3_bucket, s3_key = [
self.argument,
code.get("S3Bucket"),
Expand Down Expand Up @@ -110,7 +110,7 @@ def run(self):
md5.update(content)

try:
self.connection_manager.call(
self.stack.connection_manager.call(
service="s3",
command="head_object",
kwargs={
Expand All @@ -135,7 +135,7 @@ def run(self):
)
)

result = self.connection_manager.call(
result = self.stack.connection_manager.call(
service="s3",
command="put_object",
kwargs={
Expand Down
11 changes: 11 additions & 0 deletions hooks/s3_package/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from setuptools import setup

setup(
name='s3_package',
py_modules=['s3_package'],
entry_points={
'sceptre.hooks': [
's3_package = s3_package:S3Package',
],
}
)
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
sceptre>=1.3.4,<2
sceptre>=2
troposphere
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ def resolve(self):
self.logger.debug(
"[{}] S3 bucket/key parsed from the argument".format(self.NAME)
)
elif "sceptre_user_data" in self.stack_config:
code = self.stack_config.get("sceptre_user_data").get("Code", {})
elif self.stack.sceptre_user_data and "Code" in self.stack.sceptre_user_data:
code = self.stack.sceptre_user_data.get("Code", {})
s3_bucket, s3_key = [code.get("S3Bucket"), code.get("S3Key")]
self.logger.debug(
"[{}] S3 bucket/key parsed from sceptre_user_data['Code']".format(
Expand All @@ -26,7 +26,7 @@ def resolve(self):
"S3 bucket/key could not be parsed nor from the argument, neither from sceptre_user_data['Code']"
)

result = self.connection_manager.call(
result = self.stack.connection_manager.call(
service="s3",
command="head_object",
kwargs={"Bucket": s3_bucket, "Key": s3_key},
Expand Down
11 changes: 11 additions & 0 deletions resolvers/s3_version/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from setuptools import setup

setup(
name='s3_version',
py_modules=['s3_version'],
entry_points={
'sceptre.resolvers': [
's3_version = s3_version:S3Version',
],
}
)