diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..848be27 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3-alpine + +RUN pip install boto3 + +COPY entrypoint.py . + +ENTRYPOINT [ "entrypoint.py" ] diff --git a/README.md b/README.md new file mode 100644 index 0000000..f429e5e --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# Read Elastic Beanstalk Environment Data + +A GitHub Action to read data about an AWS Elastic Beanstalk environment. + +## Example + +```yaml +- name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: us-west-2 +- id: env_status + uses: alexjurkiewicz/elastic-beanstalk-read-environment@master + with: + application_name: My App + environment_name: production +- run: | + ver="${{ steps.env_status.output.version }}" + Currently deployed version: $ver + if [[ $ver != ${{ github.sha }} ]] ; then + echo "Not running the latest code." + exit 1 + fi +``` + +## Inputs + +You can select the environment to load data about in two ways: + +1. Exact `environment_id` match +2. Exact `environment_name` match (optionally with `application_name`) + +| Input | Required? | Description | +| --- | --- | --- | +| environment_id | No | Return data on this environment (eg `e-abcd1234yz`). | +| environment_name | No | Return data on environment with this exact name. If you have environments with the name in multiple applications, also specify `application_name`. | +| application_name | No | Restrict `environment_name` matches to this application. | + +### Environment Variables + +You need to provide AWS credentials via the [`aws-actions/configure-aws-credentials` action](https://github.com/aws-actions/configure-aws-credentials). + +## Outputs + +| Output | Description | +| --- | --- | +| name | Environment name. | +| id | Environment ID (eg `e-abcd1234yz`). | +| application | Application the environment exists in. | +| version | Currently deployed application version label. | diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..fd8f15e --- /dev/null +++ b/action.yml @@ -0,0 +1,31 @@ +name: Read Elastic Beanstalk Environment Data +author: Alex Jurkiewicz +description: Read the status of an AWS Elastic Beanstalk Environment +inputs: + application_name: + description: Application to search for the environment + required: false + default: "" + environment_name: + description: Environment name to search for + required: false + default: "" + environment_id: + description: Environment ID to load (eg `e-abcd1234yz`) + required: false + default: "" +outputs: + name: + description: Environment name + id: + description: Environment ID (eg `e-abcd1234yz`) + application: + description: Application the environment exists in + version: + description: Currently deployed application version label +runs: + using: docker + image: Dockerfile +branding: + color: green + icon: codesandbox diff --git a/entrypoint.py b/entrypoint.py new file mode 100644 index 0000000..f771b3f --- /dev/null +++ b/entrypoint.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 + +import json +import os +import sys + +import boto3 + + +def debug(msg): + print(f"::debug::{msg}") + + +def fail(msg): + print(f"::error ::{msg}") + sys.exit(1) + + +def set_output(key, val): + print(f"Set output {key}={val}") + print(f"::set-output name={key}::{val}") + + +def load_config(): + config = { + "app_name": os.environ.get("INPUT_APPLICATION_NAME"), + "env_id": os.environ.get("INPUT_ENVIRONMENT_ID"), + "env_name": os.environ.get("INPUT_ENVIRONMENT_NAME"), + } + debug(f"Loaded config: {config}") + return config + + +def validate_config(config): + if not config["app_name"] and not config["env_id"] and not config["env_name"]: + fail("You must specify at least environment_id or environment_name.") + if config["env_id"] and (config["env_name"] or config["app_name"]): + fail( + "If you specify environment_id, don't specify environment_name or application_name." + ) + if config["app_name"] and not config["env_name"]: + fail("If you specify application_name, environment_name is required.") + + +if __name__ == "__main__": + CONFIG = load_config() + validate_config(CONFIG) + + client = boto3.client("elasticbeanstalk") + + describe_environments_params = {} + if CONFIG["app_name"]: + describe_environments_params["ApplicationName"] = CONFIG["app_name"] + if CONFIG["env_id"]: + describe_environments_params["EnvironmentIds"] = [CONFIG["env_id"]] + if CONFIG["env_name"]: + describe_environments_params["EnvironmentNames"] = [CONFIG["env_name"]] + debug(f"Request params: {describe_environments_params}") + response = client.describe_environments(**describe_environments_params) + debug(f"Response: {response}") + + if len(response["Environments"]) > 1: + apps = ",".join(e["ApplicationName"] for e in response["environments"]) + fail(f"Found multiple matching environments in applications: {apps}") + + if not response["Environments"]: + fail("Found no matching environment.") + + env = response["Environments"][0] + + set_output("name", env["EnvironmentName"]) + set_output("id", env["EnvironmentId"]) + set_output("application", env["ApplicationName"]) + set_output("version", env["VersionLabel"])