Skip to content

Commit

Permalink
Merge pull request #4 from cisagov/first-commits
Browse files Browse the repository at this point in the history
Provide initial functionality
  • Loading branch information
dav3r authored May 31, 2024
2 parents 7076a8b + ce708eb commit 652ca17
Show file tree
Hide file tree
Showing 13 changed files with 613 additions and 181 deletions.
2 changes: 0 additions & 2 deletions .isort.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,5 @@ import_heading_stdlib=Standard Python Libraries
import_heading_thirdparty=Third-Party Libraries
import_heading_firstparty=cisagov Libraries

known_first_party=example

# Run isort under the black profile to align with our other Python linting
profile=black
14 changes: 4 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ ARG PY_VERSION=3.9

# Install the Python packages necessary to install the Lambda dependencies.
RUN python3 -m pip install --no-cache-dir \
pip \
setuptools \
wheel \
pip \
setuptools \
wheel \
# This version of pipenv is the minimum version to allow passing arguments
# to pip with the --extra-pip-args option.
&& python3 -m pip install --no-cache-dir "pipenv>=2022.9.8"
Expand All @@ -31,13 +31,7 @@ FROM amazon/aws-lambda-python:$PY_VERSION as build-stage
# For a list of pre-defined annotation keys and value types see:
# https://github.com/opencontainers/image-spec/blob/master/annotations.md
###
# [email protected] is a very generic email distribution, and it is
# unlikely that anyone on that distribution is familiar with the
# particulars of your repository. It is therefore *strongly*
# suggested that you use an email address here that is specific to the
# person or group that maintains this repository; for example:
# LABEL org.opencontainers.image.authors="[email protected]"
LABEL org.opencontainers.image.authors="[email protected]"
LABEL org.opencontainers.image.authors="[email protected]"
LABEL org.opencontainers.image.vendor="Cybersecurity and Infrastructure Security Agency"

# Declare it a third time so it's brought into this scope.
Expand Down
99 changes: 66 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

[![GitHub Build Status](https://github.com/cisagov/publish-egress-ip-lambda/workflows/build/badge.svg)](https://github.com/cisagov/publish-egress-ip-lambda/actions)

This is a generic skeleton project that can be used to quickly get a
new [cisagov](https://github.com/cisagov) GitHub
[AWS Lambda](https://aws.amazon.com/lambda/) project using the Python runtimes
started. This skeleton project contains [licensing information](LICENSE), as
well as [pre-commit hooks](https://pre-commit.com) and
[GitHub Actions](https://github.com/features/actions) configurations
appropriate for the major languages that we use.
This repository contains the code for a Lambda function that can scan a set
of AWS accounts and publish files (to an S3 bucket) containing the public IP
addresses of EC2 instances or Elastic IPs that have been properly tagged.
Refer to the [Lambda inputs](#lambda-inputs) section below, specifically the
`publish_egress_tag`, for more information about how to tag an instance
or EIP for publication.

## Building the base Lambda image ##

Expand All @@ -32,29 +31,11 @@ docker compose up build_deployment_package

This will output the deployment zip file in the root directory.

## Running the Lambda locally ##

The configuration in this repository allows you run the Lambda locally for
testing as long as you do not need explicit permissions for other AWS
services. This can be done with the following command:

```console
docker compose up --detach run_lambda_locally
```

You can then invoke the Lambda using the following:

```console
curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
```

The `{}` in the command is the invocation event payload to send to the Lambda
and would be the value given as the `event` argument to the handler.

Once you are finished you can stop the detached container with the following command:
To customize the name of the deployment file, you can override the
`BUILD_FILE_NAME` environment variable. For example:

```console
docker compose down
BUILD_FILE_NAME="publish_egress_ip_lambda.zip" docker compose up build_deployment_package
```

## How to update Python dependencies ##
Expand All @@ -72,12 +53,64 @@ cd src/py3.9
pipenv lock
```

## New Repositories from a Skeleton ##
## Lambda inputs ##

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| account\_ids | The list of AWS accounts to query for egress IPs to publish. | `list(string)` | n/a | yes |
| application\_tag | The name of the AWS tag whose value represents the application associated with an IP address. | `string` | `"Application"` | no |
| bucket\_name | The name of the S3 bucket to publish egress IP address information to. | `string` | n/a | yes |
| domain | The fully qualified domain hosting the published file(s) containing egress IPs. | `string` | `"egress.ips.example.gov"` | no |
| ec2\_read\_role\_name | The name of the IAM role that allows read access to the necessary EC2 attributes. Note that this role must exist in each account that you want to query and it must be assumable by Lambda. For an example policy, see [`cisagov/cool-accounts`](https://github.com/cisagov/cool-accounts/blob/develop/dynamic/ec2readonly_policy.tf). | `string` | `"EC2ReadOnly"` | no |
| file\_configs | A list of dictionaries that define the files to be published. "app_regex" specifies a regular expression that is matched against the value of the application_tag to determine if the address should be included in the file. "description" is the description of the published file. "filename" is the name to assign the published file. "static\_ips" is the list of CIDR blocks that will always be included in the published file. | `list(dict({ app_regex = string, description = string, filename = string, static_ips = list(string) }))` | n/a | yes |
| file\_header | The header template for each published file, comprised of a list of strings. When the file is published, newline characters are automatically added between each item in the list. The following variables are available within the template: `{domain}` - the domain where the published files are located, `{filename}` - the name of the published file, `{timestamp}` - the timestamp when the file was published, `{description}` - the description of the published file. | `list(string)` | `["###", "# https://{domain}/{filename}", "# {timestamp}", "# {description}", "###"]` | no |
| publish\_egress\_tag | The name of the AWS tag whose value represents whether the EC2 instance or elastic IP should have its public IP address published. | `string` | `"Publish Egress"` | no |
| region\_filters | A list of AWS EC2 region filters to use when querying for IP addresses to publish. If a filter is not specified, the query will be performed in all regions. An example filter to restrict to US regions looks like this: `[{ "Name" : "endpoint", "Values" : ["*.us-*"] }]`. For more information, refer to the [AWS EC2 CLI documentation](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-regions.html). | `list(dict({ Name = string, Values = list(string) }))` | `[]` | no |
| task | The name of the Lambda task to perform. Currently, the only valid value is `"publish"`. | `string` | n/a | yes |

## Example Lambda input ##

The following is an example of the JSON input event that is expected by the
Lambda:

```json
{
"account_ids": [
"123456789012",
"234567890123"
],
"bucket_name": "my-egress-ip-bucket",
"domain": "egress.ips.example.gov",
"file_configs": [
{
"app_regex": ".*",
"description": "This file contains a list of all IP public addresses to be published.",
"filename": "all.txt",
"static_ips": []
},
{
"app_regex": "^Vulnerability Scanning$",
"description": "This file contains a list of all IPs used for Vulnerability Scanning.",
"filename": "vs.txt",
"static_ips": [
"192.168.1.1/32",
"192.168.2.2/32"
]
}
],
"region_filters": [{
"Name": "endpoint",
"Values": ["*.us-*"]
}],
"task": "publish"
}
```

## Deploying the Lambda ##

Please see our [Project Setup guide](https://github.com/cisagov/development-guide/tree/develop/project_setup)
for step-by-step instructions on how to start a new repository from
a skeleton. This will save you time and effort when configuring a
new repository!
The easiest way to deploy the Lambda and related resources is to use the
[cisagov/publish-egress-ip-terraform](https://github.com/cisagov/publish-egress-ip-terraform)
repository. Refer to the documentation in that project for more information.

## Contributing ##

Expand Down
9 changes: 1 addition & 8 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ services:
build: .
# This uses the value of the LAMBDA_TAG environment variable from
# the invoking environment but falls back to a default value.
image: cisagov/example_lambda:${LAMBDA_TAG:-latest}
image: cisagov/publish_egress_ip_lambda:${LAMBDA_TAG:-latest}
entrypoint: /opt/build_artifact.sh
environment:
# This uses the value of the BUILD_FILE_NAME environment variable
Expand All @@ -15,10 +15,3 @@ services:
volumes:
- ./src/build_artifact.sh:/opt/build_artifact.sh
- .:/var/task/output
run_lambda_locally:
build: .
# This uses the value of the LAMBDA_TAG environment variable from
# the invoking environment but falls back to a default value.
image: cisagov/example_lambda:${LAMBDA_TAG:-latest}
ports:
- "9000:8080"
3 changes: 3 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
--requirement requirements-test.txt
# boto3 is not strictly required, but it can be useful for some local
# development testing activities, so we include it here as a convenience.
boto3
ipython
pipenv
semver
Loading

0 comments on commit 652ca17

Please sign in to comment.