-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit; Implements the Basic Routing Policy
- Loading branch information
0 parents
commit bbd00fa
Showing
6 changed files
with
257 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.aws |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
FROM python:3.8-alpine | ||
RUN apk update && pip3 install boto3 | ||
COPY change.py /change.py | ||
ENTRYPOINT ["python3", "/change.py"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Copyright (c) 2020 Julian Pelizäus | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# AWS Route 53 Record Set | ||
|
||
This GitHub Actions allows you to manage [AWS Route 53](https://aws.amazon.com/route53/) Record Sets. | ||
|
||
The naming is aligned with the official interface: https://docs.aws.amazon.com/cli/latest/reference/route53/change-resource-record-sets.html. There you can find possible variations for every Input this GitHub Action supports. | ||
|
||
## Get started | ||
|
||
A new AWS Route 53 Record Set can be created with the following workflow syntax: | ||
|
||
```yaml | ||
jobs: | ||
aws_route53: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: "Create an A record set" | ||
uses: Roosterfish/aws-route53-record-set-action@master | ||
with: | ||
aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
aws_route53_hosted_zone_id: ${{ secrets.AWS_ROUTE53_HOSTED_ZONE_ID }} | ||
aws_route53_rr_action: "CREATE" | ||
aws_route53_rr_name: "your-fqdn.example.com" | ||
aws_route53_rr_type: "A" | ||
aws_route53_rr_ttl: "300" | ||
aws_route53_rr_value: "1.2.3.4" | ||
``` | ||
# GitHub Action Inputs | ||
The behaviour of this Action can be modified with the following Inputs: | ||
Name | Description | Choices | Required | ||
--- | --- | --- | --- | ||
`aws_access_key_id` | The AWS access key id | | yes | ||
`aws_secret_access_key` | The AWS secret access key | | yes | ||
`aws_route53_hosted_zone_id` | The id of the hosted zone | | yes | ||
`aws_route53_rr_action` | The action that should be taken | `CREATE`, `DELETE`, `UPSERT` | yes | ||
`aws_route53_rr_name` | The name of the record set | | yes | ||
`aws_route53_rr_type` | The type of the record set | `SOA`, `A`, `TXT`, `NS`, `CNAME`, `MX`, `PTR`, `SRV`, `SPF`, `AAAA` | yes | ||
`aws_route53_rr_ttl` | The TTL of the record set | | yes | ||
`aws_route53_rr_value` | The value of the record set | | yes | ||
`aws_route53_rr_comment` | A comment for the record set | | no | ||
`aws_route53_wait` | Wait until the record set is fully settled in | `true`, `false` | no | ||
|
||
## Supported Routing Policies | ||
|
||
Currently this GitHub Actions supports the following Routing Policies of the AWS Route 53 service: | ||
|
||
Name | Extra Variables | ||
--- | --- | ||
Basic | None | ||
|
||
## License | ||
|
||
The MIT License (MIT) | ||
|
||
Copyright (c) 2020 Julian Pelizäus | ||
|
||
### Used libraries | ||
|
||
https://pypi.org/project/boto3/ licensed under [Apache License 2.0](https://github.com/boto/boto3/blob/develop/LICENSE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
name: AWS Route 53 Record Set | ||
author: Julian Pelizäus <jp@adformc.de> | ||
branding: | ||
icon: cloud | ||
color: gray-dark | ||
description: Create Route 53 Record Sets | ||
inputs: | ||
aws_access_key_id: | ||
description: The AWS access key id | ||
required: true | ||
aws_secret_access_key: | ||
description: The AWS secret access key | ||
required: true | ||
aws_route53_hosted_zone_id: | ||
description: The id of the hosted zone | ||
required: true | ||
aws_route53_rr_action: | ||
description: The action that should be taken | ||
required: true | ||
aws_route53_rr_name: | ||
description: The name of the record set | ||
required: true | ||
aws_route53_rr_type: | ||
description: The type of the record set | ||
required: true | ||
aws_route53_rr_ttl: | ||
description: The TTL of the record set | ||
required: true | ||
aws_route53_rr_value: | ||
description: The value of the record set | ||
required: true | ||
aws_route53_rr_comment: | ||
description: A comment used for the resource record | ||
required: false | ||
aws_route53_wait: | ||
description: Wait until the record set is fully settled in | ||
required: false | ||
runs: | ||
using: docker | ||
image: Dockerfile |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import os | ||
import sys | ||
import json | ||
import boto3 | ||
|
||
from distutils import util | ||
|
||
|
||
class AWSRoute53RecordSet: | ||
""" | ||
Primary class for the handling of AWS Route 53 Record Sets. | ||
""" | ||
def __init__(self): | ||
""" | ||
The default constructor. | ||
""" | ||
self.client = None | ||
self.waiter = None | ||
self.rr_skeleton = dict() | ||
|
||
def _get_env(self, variable, exit=True): | ||
""" | ||
Try to fetch a variable from the environment. | ||
Per default the method will raise an exception if the variable isn't present. | ||
This behaviour can be switched off via the exit flag. | ||
""" | ||
value = os.environ.get(variable) | ||
if not value and exit: | ||
raise NameError("Cannot find environment variable: " + str(variable)) | ||
return value | ||
|
||
def _connect(self): | ||
""" | ||
Creates a new client object which wraps the connection to AWS. | ||
""" | ||
if not self.client: | ||
self.client = boto3.client( | ||
"route53", | ||
aws_access_key_id=self._get_env("INPUT_AWS_ACCESS_KEY_ID"), | ||
aws_secret_access_key=self._get_env("INPUT_AWS_SECRET_ACCESS_KEY") | ||
) | ||
self.waiter = self.client.get_waiter("resource_record_sets_changed") | ||
|
||
def _set_comment(self): | ||
""" | ||
Appends an additional comment field to the record set. | ||
""" | ||
comment = self._get_env("INPUT_AWS_ROUTE53_RR_COMMENT", False) | ||
if comment: | ||
self.rr_skeleton["Comment"] = comment | ||
|
||
def _set_base_changes(self): | ||
""" | ||
Creates the base skeleton required for creating a new record set. | ||
""" | ||
self.rr_skeleton["Changes"] = [{ | ||
"Action": self._get_env("INPUT_AWS_ROUTE53_RR_ACTION"), | ||
"ResourceRecordSet": { | ||
"Name": self._get_env("INPUT_AWS_ROUTE53_RR_NAME"), | ||
"Type": self._get_env("INPUT_AWS_ROUTE53_RR_TYPE"), | ||
"TTL": int(self._get_env("INPUT_AWS_ROUTE53_RR_TTL")), | ||
"ResourceRecords": [{ | ||
"Value": self._get_env("INPUT_AWS_ROUTE53_RR_VALUE") | ||
}] | ||
} | ||
}] | ||
|
||
def _build_record_set(self): | ||
""" | ||
Builds up the skeleton used for modulating the record set. | ||
""" | ||
self._set_comment() | ||
self._set_base_changes() | ||
return self.rr_skeleton | ||
|
||
def _change_record_set(self, record_set): | ||
""" | ||
Requests the required change at AWS. | ||
""" | ||
return self.client.change_resource_record_sets( | ||
HostedZoneId=self._get_env("INPUT_AWS_ROUTE53_HOSTED_ZONE_ID"), | ||
ChangeBatch=record_set | ||
) | ||
|
||
def _wait(self, request_id): | ||
""" | ||
Waits until the requested operations is finished. | ||
""" | ||
wait = self._get_env("INPUT_AWS_ROUTE53_WAIT", False) | ||
if wait and util.strtobool(wait): | ||
self.waiter.wait( | ||
Id=request_id, | ||
WaiterConfig={ | ||
"Delay": 10, | ||
"MaxAttempts": 50 | ||
} | ||
) | ||
|
||
def _obtain_request_id(self, result): | ||
""" | ||
Grabs and returns the id of the given request. | ||
""" | ||
return result["ChangeInfo"]["Id"] | ||
|
||
def _obtain_marshalled_result(self, result): | ||
""" | ||
Grabs and returns the HTTP response of the given request. | ||
""" | ||
return json.dumps(result["ResponseMetadata"], indent=4) | ||
|
||
def change(self): | ||
""" | ||
Entrypoint for the management of a record set. | ||
""" | ||
self._connect() | ||
record_set = self._build_record_set() | ||
result = self._change_record_set(record_set) | ||
self._wait( | ||
self._obtain_request_id(result) | ||
) | ||
sys.stdout.write( | ||
self._obtain_marshalled_result(result) + "\n" | ||
) | ||
|
||
|
||
try: | ||
o = AWSRoute53RecordSet() | ||
o.change() | ||
except Exception as e: | ||
sys.stderr.write(str(e) + "\n") | ||
sys.exit(1) |