SkillAgentSearch skills...

Stratosphere

Google Cloud Platform Deployment Manager tool. Like Troposphere+ for Google Cloud Platform (GCP)

Install / Use

/learn @victortrac/Stratosphere
About this skill

Quality Score

0/100

Category

Operations

Supported Platforms

Universal

README

Stratosphere

A library and tool for creating Google Cloud Platform Deployment Manager templates.

Stratosphere is inspired by Troposphere for AWS.

Features

  • Lets you write pure python
  • Includes property and type validation
  • Interacts directly with the GCP Deployment Manager API without having to use the clunky gcloud CLI
  • Highly opinionated about naming to enforce consistent naming across deployments

Installation

Create a python3 virtualenv, Git clone this repository, run installer:

# virtualenv --python=/usr/bin/python3 stratosphere   # only tested on python3
# source stratosphere/bin/activate
# cd ~/code/   <- or whever you want to put temporary stratosphere files
# git clone https://github.com/victortrac/stratosphere
# cd stratosphere
# python setup.py install

You'll need to get a valid OAuth auth JSON file to interact with the GCP DM API. This is most easily done by just installing the GCP API Client Library for Python.

Examples

Let's say you want to programmatically create a GCP network with custom ranges (example is if the default range conflicts with other networks). You can write a constants file that looks like this:

$ cat example_templates/constants.py
ENV = {
    "dev": {
        "cidr": "10.128.0.0/14",
        "subnetworks": [
            {
                "region": "us-central1",
                "cidr": "10.128.0.0/20"
            },
            {
                "region": "us-west1",
                "cidr": "10.128.32.0/20"
            },
            {
                "region": "us-east1",
                "cidr": "10.128.64.0/20"
            },
            {
                "region": "europe-west1",
                "cidr": "10.128.96.0/20"
            },
            {
                "region": "asia-east1",
                "cidr": "10.128.128.0/20"
            }
        ]
    }
}

Then write a stratosphere template that looks like this:

$ cat example_templates/networks.py
from stratosphere.resources import Template
from stratosphere.compute import Firewall, Network, Subnetwork
from stratosphere.compute_properties import FirewallAllowedPorts

import constants


class Networks(Template):
    TEMPLATE_TYPE = 'networks'

    def configure(self):
        network = Network(
            name='{}-network'.format(self.env),
            description='{} - Multi-region Network'.format(self.name),
            autoCreateSubnetworks=False,
        )

        self.add_resource(network)

        for subnetwork in constants.ENV[self.env]['subnetworks']:
            self.add_resource(
                Subnetwork(
                    name='{}-{}-subnetwork'.format(self.env, subnetwork['region']),
                    region=subnetwork['region'],
                    description='{} - {} Subnetwork'.format(self.env, subnetwork['region']),
                    ipCidrRange=subnetwork['cidr'],
                    network=network.Ref
                )
            )

Use stratosphere to validate and generate YAML:

$ stratosphere --project [MyGCPProject] --env dev --action template ./example_templates/networks.py
2016-09-29 13:09:04 INFO:stratosphere.stratosphere:Log level: 20
2016-09-29 13:09:04 INFO:stratosphere.stratosphere:Template successfully rendered, printing to stdout...
resources:
- name: dev-network
  properties: {autoCreateSubnetworks: false, description: dev-networks - MultiAZ Network,
    name: dev-network}
  type: compute.v1.network
- name: dev-us-central1-subnetwork
  properties: {description: dev - us-central1 Subnetwork, ipCidrRange: 10.128.0.0/20,
    name: dev-us-central1-subnetwork, network: $(ref.dev-network.selfLink), region: us-central1}
  type: compute.v1.subnetworks
- name: dev-us-west1-subnetwork
  properties: {description: dev - us-west1 Subnetwork, ipCidrRange: 10.128.32.0/20,
    name: dev-us-west1-subnetwork, network: $(ref.dev-network.selfLink), region: us-west1}
  type: compute.v1.subnetworks
- name: dev-us-east1-subnetwork
  properties: {description: dev - us-east1 Subnetwork, ipCidrRange: 10.128.64.0/20,
    name: dev-us-east1-subnetwork, network: $(ref.dev-network.selfLink), region: us-east1}
  type: compute.v1.subnetworks
- name: dev-europe-west1-subnetwork
  properties: {description: dev - europe-west1 Subnetwork, ipCidrRange: 10.128.96.0/20,
    name: dev-europe-west1-subnetwork, network: $(ref.dev-network.selfLink), region: europe-west1}
  type: compute.v1.subnetworks
- name: dev-asia-east1-subnetwork
  properties: {description: dev - asia-east1 Subnetwork, ipCidrRange: 10.128.128.0/20,
    name: dev-asia-east1-subnetwork, network: $(ref.dev-network.selfLink), region: asia-east1}
  type: compute.v1.subnetworks

This reads the networks.py template and generates a valid Google Compute Engine Deployment Manager YAML config, reading values from a constants.py that is shared across your deployments.

If you want to create the network, instead of --action template, you would run --action apply:

$ stratosphere --project [MyGCPProject] --env dev --action apply ./example_templates/networks.py
2016-09-29 13:10:59 INFO:stratosphere.stratosphere:Log level: 20
2016-09-29 13:10:59 INFO:root:Generated template:
resources:
- name: dev-network
  properties: {autoCreateSubnetworks: false, description: dev-networks - MultiAZ Network,
    name: dev-network}
  type: compute.v1.network
- name: dev-us-central1-subnetwork
  properties: {description: dev - us-central1 Subnetwork, ipCidrRange: 10.128.0.0/20,
    name: dev-us-central1-subnetwork, network: $(ref.dev-network.selfLink), region: us-central1}
  type: compute.v1.subnetworks
- name: dev-us-west1-subnetwork
  properties: {description: dev - us-west1 Subnetwork, ipCidrRange: 10.128.32.0/20,
    name: dev-us-west1-subnetwork, network: $(ref.dev-network.selfLink), region: us-west1}
  type: compute.v1.subnetworks
- name: dev-us-east1-subnetwork
  properties: {description: dev - us-east1 Subnetwork, ipCidrRange: 10.128.64.0/20,
    name: dev-us-east1-subnetwork, network: $(ref.dev-network.selfLink), region: us-east1}
  type: compute.v1.subnetworks
- name: dev-europe-west1-subnetwork
  properties: {description: dev - europe-west1 Subnetwork, ipCidrRange: 10.128.96.0/20,
    name: dev-europe-west1-subnetwork, network: $(ref.dev-network.selfLink), region: europe-west1}
  type: compute.v1.subnetworks
- name: dev-asia-east1-subnetwork
  properties: {description: dev - asia-east1 Subnetwork, ipCidrRange: 10.128.128.0/20,
    name: dev-asia-east1-subnetwork, network: $(ref.dev-network.selfLink), region: asia-east1}
  type: compute.v1.subnetworks


2016-09-29 13:10:59 INFO:root:Launching a new deployment: dev-networks

Continue? (yes/no) yes
Running in 5...4...3...2...1...
Waiting for deployment operation-1475172676856-53da96762e8c0-ce3bcf31-fb776453...
2016-09-29 13:11:18 INFO:stratosphere.stratosphere:Operation: operation-1475172676856-53da96762e8c0-ce3bcf31-fb776453, TargetLink: https://www.googleapis.com/deploymentmanager/v2/projects/MyGCPProject/global/deployments/dev-networks, Progress: 0, Status: RUNNING
...
2016-09-29 13:12:18 INFO:stratosphere.stratosphere:Operation: operation-1475172676856-53da96762e8c0-ce3bcf31-fb776453, TargetLink: https://www.googleapis.com/deploymentmanager/v2/projects/MyGCPProject/global/deployments/dev-networks, Progress: 100, Status: DONE
Stack action complete.

Let's now say you want to add some firewall rules. Modify networks.py to include this:

    firewall_rules = [
        Firewall(
            name='{}-internal-ssh'.format(network.name),
            network=network.Ref,
            allowed=[
                FirewallAllowedPorts(
                    IPProtocol=FirewallAllowedPorts.TCP,
                    ports=['22']
                ),
                FirewallAllowedPorts(
                    IPProtocol=FirewallAllowedPorts.ICMP
                )
            ],
            sourceRanges=[
                constants.ENV[self.env]['cidr']
            ]
        )
    ]

    [self.add_resource(f) for f in firewall_rules]

Run --action apply again and see a diff:

$ stratosphere --project [MyGCPProject] --env dev --action apply ./example_templates/networks.py
2016-09-29 13:59:58 INFO:stratosphere.stratosphere:Log level: 20
2016-09-29 13:59:58 INFO:root:Deployment already exists. Getting changes for dev-networks...
--- Existing template

+++ Proposed template

@@ -23,3 +23,13 @@

   properties: {description: dev - asia-east1 Subnetwork, ipCidrRange: 10.128.128.0/20,
     name: dev-asia-east1-subnetwork, network: $(ref.dev-network.selfLink), region: asia-east1}
   type: compute.v1.subnetworks
+- name: dev-network-internal-ssh
+  properties:
+    allowed:
+    - IPProtocol: tcp
+      ports: ['22']
+    - {IPProtocol: icmp}
+    name: dev-network-internal-ssh
+    network: $(ref.dev-network.selfLink)
+    sourceRanges: [10.128.0.0/14]
+  type: compute.v1.firewall

Continue? (yes/no)

Simply enter 'yes' and you'll have some firewall rules.

See the example_templates directory for more template examples.

Local Validation Examples

Stratosphere resources know about required parameters, so if you define a resource that is missing a parameter or has an invalid field, you'll get an error like this (without having to wai

View on GitHub
GitHub Stars25
CategoryOperations
Updated4y ago
Forks4

Languages

Python

Security Score

60/100

Audited on Feb 18, 2022

No findings