Home

Awesome

swag_client

PyPi

Build Status

OSS Status

SWAG is a collection of repositories used to keep track of the metadata describing cloud accounts. Originally built to store data on AWS, swag is flexible enough to be used for multiple providers (AWS, GCP, etc.,).

For applications that manage or deploy to several different accounts/environments SWAG provides a centralized metadata store.

Managing your cloud accounts with SWAG allows for consuming application to focus on business logic, removing hardcoded lists or properties from your application.

Related Projects

These projects are part of the SWAG family and either manipulate or utilize SWAG data.

swag-api - Rest API and UI for SWAG Data

swag-functions - Transformation functions for SWAG Data

Installation

swag-client is available on pypi:

    pip install swag_client

Basic Usage

If no options are passed to the SWAGManager it is assumed that you are using the file backend and the account namespace.

    from swag_client.backend import SWAGManager
    from swag_client.util import parse_swag_config_options

    swag_opts = {}
    swag = SWAGManager(**parse_swag_config_options(swag_opts))

    account = swag.get_by_name('account')

Configure SWAG by passing the client additional keyword arguments:

    from swag_client.backend import SWAGManager
    from swag_client.util import parse_swag_config_options

    swag_opts = {
        'swag.type': 's3',
        'swag.bucket_name': s3_bucket_name
    }

    swag = SWAGManager(**parse_swag_config_options(swag_opts))

Additionally SWAG can be used a singleton, allowing a single instance (and it's cache) to be shared across an application.

Declare swag in a file like extensions.py:

    from swag_client.backend import SWAGManager
    from swag_client.util import parse_swag_config_options

    swag = SWAGManager()

When you're ready to configure swag:

    from extensions import swag

    swag_opts = {
        'swag.type': 's3',
        'swag.bucket_name': s3_bucket_name
    }

    swag.configure(**parse_swag_config_options(swag_opts))

Example Account JSON (v2)

Below is an example of the bare minimum JSON that will be created by SWAG with schema_version=2.

 [{
    "aliases": ["test"],
    "contacts": ["admins@test.net"],
    "description": "This is just a test.",
    "email": "test@example.net",
    "environment": "test",
    "id": "012345678910",
    "name": "testaccount",
    "owner": "ExampleCorp",
    "provider": "aws",
    "sensitive": false
 }]

Additionally SWAG has the ability to store metadata for services that may need to be tied to an account.

 [{
    "id": "012345678910",
    ...
    "services": [
        {
            "name": "myService",
            "metadata": {
                "name": "testService"
            },
            "status": [
                {
                    "region": "all",
                    "enabled": true
                }
            ]
        }
    ]
 }]

This service metadata for serving as a single source of truth for applications that have to routinely manage/monitor/process multiple accounts.

Filtering

Regardless of backend, SWAG uses the jmespath syntax for filtering data.

    swag.get("[?id=='012345678910']")  # valid jmespath filter

More information on jmespath filtering: http://jmespath.org/tutorial.html

Old-style (deprecated)

SWAG also supports an older style calling convention. This convention only supports the S3 backend, additionally these functions are now deprecated and will be removed in the future.

    from swag_client.swag import get_all_accounts
    get_all_accounts(bucket='your-swag-bucket').get('accounts')

or to filter by a service tag:

    service = {'services': {'YOURSERVICE': {'enabled': True, 'randomflag': True}}}
    get_all_accounts(bucket='your-swag-bucket', **service).get('accounts')

Versioning

All SWAG metadata is versioned. The most current version of the account metadata schema is v2. SWAG further provides the ability to transform data between schema version as necessary.

Backends

SWAG supports multiple backends, included in the package are file, s3, and dynamodb backends. Additional backends can easily be created and integrated into SWAG.

Global Backend Options

KeyTypeRequiredDescription
swag.typestrfalseType of backend to use (Default: 'file')
swag.namespacestrfalseNamespace for metadata (Default: 'accounts')
swag.schema_versionintfalseSchema version that will be returned to the caller. (Default: 'v2')
swag.cache_expiresintfalseNumber of seconds to cache backend results (Default: 60)

S3 Backend

The S3 backend uses AWS S3 to SWAG metadata.

Backend Options

KeyTypeRequiredDescription
swag.bucket_namestrtrueRaw S3 bucket name
swag.data_filestrfalseFull S3 key of file
swag.regionstrfalseRegion the bucket exists in. (Default: us-east-1)

Permissions

IAM Permissions required:

    {
        "Action": ["s3:GetObject"],
        "Effect": ["Allow"],
        "Resource: ["arn:aws:s3:::<swag-bucket-name>/<data-file>"]
    }

If you wish to update SWAG metadata you will also need the following permissions:

    {
        "Action": ["s3:PutObject"],
        "Effect": ["Allow"],
        "Resource: ["arn:aws:s3:::<swag-bucket-name>/<data-file>"]
    }

File Backend

The file backend uses a file on the local filesystem. This backend is often useful for testing purposes but it not scalable to multiple clients.

Backend Options

KeyTypeRequiredDescription
swag.data_dirstrfalseDirectory to store data (Default: cwd())
swag.data_filestrfalseFull path to data file

DynamoDB Backend

The DynamoDB backend leverages AWSs DynamoDB as a key value store for SWAG metadata.

SWAG expects a Dynamodb Table already exists.

Create a new table via the AWS console named accounts with a primary key of id.

Backend Options

KeyTypeRequiredDescription
swag.regionstrfalseRegion dynamodb table exists

Note the above options except region is only needed if not SWAG table has been created.

Permissions

Minimum Permissions required:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DescribeQueryTable",
            "Effect": "Allow",
            "Action": [
                "dynamodb:DescribeTable",
                "dynamodb:Query",
                "dynamodb:Scan"
            ],
            "Resource": "*"
        }
    ]
}

If you wish SWAG to modify your table you will need the following additional permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PutUpdateDeleteTable",
            "Effect": "Allow",
            "Action": [
                "dynamodb:PutItem",
                "dynamodb:UpdateItem",
                "dynamodb:DeleteItem"
            ],
            "Resource": "*"
        }
    ]
}

CLI Usage

Upon installation the swag_client creates a swag entrypoint which invokes the swag_client cli, example usage:

Examples:

    swag --help

Extended SWAG Schema (Version 2)

The following describes the usage of all native fields included within the SWAG schema.

NameTypeDescription
schemaVersionintDescribes the current schema version
idstrUnique ID of the account
namestrCanonical name, according to the account naming standard
contactslist(str)List of team DLs that are majority stakeholders for the account
providerstrOne of: AWS, GCP, Azure
typestrSee schema context for field validation
statuslist(dict)See status schema
serviceslist(dict)See service schema
environmentstrSee schema context for field validation
sensitiveboolSignifies if the account holds a special significance; (in scope for PCI, holds PII, contains sensitive key material, etc.,)
descriptionstrBrief description about the account's intended use.
ownerstrSee schema context for field validation
aliaseslist(str)List of other names this account may be referred to as

Schmea Context for Field Validation

The V2 schema performs validation checks on certain fields to ensure values are within a defined list. Some of these are optional and configurable to allow users to specify values that make sense for their use case.

The allowed values for owner, environment and type can be set during SWAGManager initialization by passing a swag.schema_context object as part of the swag_opts.

If you do not specify a schema_context entry for a field then any value is permitted.

swag_opts = {
    'swag.schema_context': {
        'owner': ['netflix', 'dvd', 'aws', 'third-party'],
        'environment': ['test', 'prod'],
        'type': ['billing', 'security', 'shared-service', 'service']
    }
}

Service Schema

NameTypeDescription
namestrName of the service
regionslist(str)List of regions - empty list indicates all regions
roleslist(dict)List of roles that control access to this service. See role schema
metadatadictService Level metadata

Status Schema

NameTypeDescription
regionstrStatus per-region
statusstrOne of: Created, In-progress, Ready, Deprecated, In-active, Deleted
noteslist(dict)See notes schema

Notes Schema

NameTypeDescription
datedateDate note was created
textstrFree text field with additional information

Roles Schema

NameTypeDescription
idstrId of the role
policyUrlstrURL with link to role permissions
roleNamestrCorresponding AWS role (if any)
googleGroupstrCorresponding google group
secondaryApproverstrDL needed to approve role

Definitions

Status

Created - Account has been created but infrastructure has not yet been established

In-progress - Account infrastructure is currently being deployed

Ready - Account is ready for deployment

Deprecated - Account has been marked as deprecated, no new services should be deployed into this account

In-active - Account has been evacuated of all services

Deleted - Account has been marked as deleted

Type

Billing Account(s) - The billing account in a multiple account architecture provides a central account for billing aggregation across the environment. Typically, no AWS resources (e.g. instances) run in the billing account.

Security Account(s) - The security account in a multiple account architecture provides environments for central log collection and analysis (e.g. CloudTrail, VPC Flow Logs) and security monitoring (e.g. configuration monitoring with Security Monkey, active security scanning and testing with other tools).

Shared Service Account(s) - Shared service accounts provide infrastructure, data, and services across the organization. All service/resource accounts will typically have network connectivity to shared service accounts.

Service/Resource Account Groups - Service/resource account groups host the bulk of systems and applications. Account groups are created based on various dimensions and will typically have production and test elements (separate accounts). Service/resource accounts may optionally have connectivity to other service/resource accounts.

See sample_accounts.json an example of the current json data created by SWAG.