[PYTHON] Automatisierung des Infrastrukturbaus mit CloudFromation + Tropical + AWS Lambda

Ich habe versucht, mithilfe der Troposphäre ein Tool zur Vorlagenerstellung für CloudFormation zu erstellen. Durch Ausführen des erstellten Tools auf Lambda habe ich versucht, eine Vorlage zu erstellen, indem ich das Parameterblatt auf S3 platziert habe.

Das JSON-Format ist schwer zu schreiben.

Vor kurzem hatte ich die Möglichkeit, CloudFormation in meinem Unternehmen zu berühren. Ich denke, der Engpass bei der Verwendung von CloudFormation ist die Datei im JSON-Format.

python


{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "hogehoge",
    "Resources": {
        "test1": {
            "Properties": {
                "CidrBlock": "10.1.0.0/16",
                "EnableDnsHostnames": "true",
                "EnableDnsSupport": "true",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "test1"
                    }
                ]
            },
            "Type": "AWS::EC2::VPC"
        },
        "test2": {
            "Properties": {
                "CidrBlock": "10.2.0.0/16",
                "EnableDnsHostnames": "true",
                "EnableDnsSupport": "true",
                "Tags": [
                    {
                        "Key": "Name",
                        "Value": "test2"
                    }
                ]
            },
            "Type": "AWS::EC2::VPC"
        }
    }
}

Nur zwei VPCs herzustellen, sieht so aus. Ich denke, es ist eine ziemliche Handwerkskunst, dies von Hand zu schreiben.

Was ist Troposphäre?

troposphere ist ein Tool zum Erstellen einer solchen Datei im JSON-Format durch Schreiben in Python. https://github.com/cloudtools/troposphere Der obige Code kann auch wie folgt leicht lesbar geschrieben werden, indem er mit Tropical geschrieben wird.

python


import json
from troposphere import Tags,Template
from troposphere.ec2 import VPC
t = Template()
t.add_version("2010-09-09")
t.add_description("hogehoge")
t.add_resource(VPC(
              "test1",
              EnableDnsSupport="true",
              CidrBlock="10.1.0.0/16",
              EnableDnsHostnames="true",
              Tags=Tags(
                    Name="test1"
                    )
              )) 
t.add_resource(VPC(
              "test1",
              EnableDnsSupport="true",
              CidrBlock="10.2.0.0/16",
              EnableDnsHostnames="true",
              Tags=Tags(
                    Name="test2"
                    )
              ))
json_template = t.to_json()
print(json_template)                

Die grundlegende Verwendung besteht darin, den Versionsnamen und die Beschreibung mit add_version und add_description zu beschreiben und dann weitere Ressourcen hinzuzufügen, die mit add_resource erstellt werden sollen. Es ist nicht dramatisch einfacher zu lesen, aber ich denke, es ist ein bisschen besser als es im JSON-Format zu schreiben. Außerdem ist es nicht nur einfacher zu sehen, sondern der Punkt ist auch, dass Sie Python für und if-Anweisungen verwenden können. Es ist einfach, eine große Menge von Ressourcen zu beschreiben, indem mehrere CIDR-Blöcke und -Namen als Array übergeben werden.

python


import json
from troposphere import Tags,Template
from troposphere.ec2 import VPC
t = Template()
t.add_version("2010-09-09")
t.add_description("hogehoge")
VPC_CidrBlockList = ["10.1.0.0/16","10.2.0.0/16"]
VPC_TagsNameList = ["test1","test2"]
for (Address,Tag_Name) in zip(VPC_CidrBlockList,VPC_TagNameList):
t.add_resource(VPC(
              Tag_Name,
              EnableDnsSupport="true",
              CidrBlock=Address,
              EnableDnsHostnames="true",
              Tags=Tags(
                    Name=Tag_Name
                    )
              )) 
json_template = t.to_json()
print(json_template)                

Bringen Sie den eingestellten Wert von außen.

Im obigen Zustand werden übrigens die Einstellungswerte wie CIDR-Block und Name in das Skript geschrieben, dies ist jedoch schwierig zu verwenden. Lesen wir die Parameter von außen und speichern sie in einem Array, damit sie verwendet werden können. In diesem Fall sind zwei Arten von Informationen als Parameter erforderlich (CIDR-Block, Name). Erstellen Sie daher ein Parameterblatt wie unten gezeigt und speichern Sie es als Textdatei.

  1. Zeile 10.1.0.0/16, 10.2.0.0/16
  2. Zeile Test1, Test2

Öffnen und laden Sie nach dem Erstellen einer Textdatei zunächst diese Textdatei.

python


f = open('test.txt')
test = f.read()
f.close

Die Daten werden jetzt im Test gespeichert. In diesem Zustand sind jedoch die erste und die zweite Zeile nicht getrennt. Verwenden Sie also Splitlines, um jede Zeile als Array zu speichern.

python


test_list= test.splitlines()

Dadurch wird eine Array-Testliste mit jeder Zeile als Element erstellt. ["10.1.0.0/16,10.2.0.0/16","test1,test2"] Darüber hinaus wird hier die Aufteilung verwendet, um ein Array für jeden Parameter zu erstellen.

python


VPC_CidrBlockList = test_list[0].split(',')
VPC_TagNameList = test_list[1].split(',')

Jetzt haben Sie ein Array von Parametern erstellt. Wenn Sie diese Vorgänge einbinden und das vorherige Skript ändern, sieht es wie folgt aus.

python


import json
from troposphere import Tags,Template
from troposphere.ec2 import VPC

f = open('test.txt')
test = f.read()
f.close
test_list= test.splitlines()
VPC_CidrBlockList = test_list[0].split(',')
VPC_TagNameList = test_list[1].split(',')

t = Template()
t.add_version("2010-09-09")
t.add_description("hogehoge")
for (Address,Tag_Name) in zip(VPC_CidrBlockList,VPC_TagNameList):
t.add_resource(VPC(
              Tag_Name,
              EnableDnsSupport="true",
              CidrBlock=Address,
              EnableDnsHostnames="true",
              Tags=Tags(
                    Name=Tag_Name
                    )
              )) 
json_template = t.to_json()
print(json_template)                

Sie können jetzt mehrere VPCs gemäß den im Parameterblatt aufgeführten Parametern erstellen.

Versuchen Sie es mit AWS Lambda.

Der grundlegende Teil der Verwendung von Lambda bleibt derselbe, aber der Prozess des Abrufens des Parameterblatts aus dem S3-Bucket und der Prozess des Hochladens der erstellten Vorlage in den S3-Bucket wurden hinzugefügt.

python


# coding: utf-8

import json
import urllib
import boto3
from troposphere import Tags,Template
from troposphere.ec2 import VPC
from datetime import datetime

basename = datetime.now().strftime("%Y%m%d-%H%M%S")

print('Loading function')

s3 = boto3.resource('s3')

def lambda_handler(event, context):
        #print("Received event: " + json.dumps(event, indent=2))

        # Get the object from the event and show its content type
        bucket = event['Records'][0]['s3']['bucket']['name']
        key = urllib.unquote_plus(event['Records'][0]['s3']['object']['key']).decode('utf8')
        print ("buket:" + bucket)
        print ("key:" + key)
        obj = s3.Object(bucket,key)
        response= obj.get()
        body = response['Body'].read()
        body_list= body.splitlines()
        # u'Erstellen einer VPC'
        VPC_CidrBlockList = body_list[0].split(',')
        VPC_TagNameList= body_list[1].split(',')

        t = Template()
        t.add_version("2010-09-09")
        t.add_description("hogehoge")
        for (Address,Tag_Name) in zip(VPC_CidrBlockList,VPC_TagNameList):
            t.add_resource(VPC(
                  Tag_Name,
                  EnableDnsSupport="true",
                  CidrBlock=Address,
                  EnableDnsHostnames="true",
                  Tags=Tags(
                        Name=Tag_Name
                  )
            )) 
        json_template = t.to_json()
        bucket = s3.Bucket('template_test')
        obj = bucket.Object('json-template-' + basename + ' .txt')
        response = obj.put(
                       Body=json_template.encode('utf-8'),
                       ContentEncoding='utf-8',
                       ContentType='text/plane'
                    )
        print(json_template)                

Sie können es auch flexibler festlegen, indem Sie die Elemente ändern, die als Variablen festgelegt werden sollen (z. B. "EnableDnsHostnames" in VPC). Wenn Sie andere Ressourcen auf diese Weise beschreiben, können Sie automatisch Vorlagen wie Subnetze und Sicherheitsgruppen sowie VPCs erstellen.

Recommended Posts

Automatisierung des Infrastrukturbaus mit CloudFromation + Tropical + AWS Lambda
PyTorch mit AWS Lambda [Lambda-Import]
Ruby-Umgebungskonstruktion mit aws EC2
[AWS] API mit API Gateway + Lambda erstellen
Benachrichtigen Sie HipChat mit AWS Lambda (Python)
[AWS] Verwenden von INI-Dateien mit Lambda [Python]
Stellen Sie mit AWS Lambda Python eine Verbindung zu s3 her
[AWS] Machen Sie SSI-ähnliche Dinge mit S3 / Lambda
Ich habe gerade FizzBuzz mit AWS Lambda gemacht
[AWS SAM] Erstellen Sie eine API mit DynamoDB + Lambda + API Gateway
Regelmäßiges Serverless Scraping mit AWS Lambda + Scrapy Teil 1.8
LINE BOT mit Python + AWS Lambda + API Gateway
Serverlose Anwendung mit AWS SAM! (APIGATEWAY + Lambda (Python))
[AWS] Versuchen Sie, API Gateway + Lambda mit X-Ray zu verfolgen
Ich habe versucht, AWS Lambda mit anderen Diensten zu verbinden
Dynamische HTML-Seiten mit AWS Lambda und Python
[AWS] Spielen mit Schrittfunktionen (SAM + Lambda) Teil 3 (Zweig)
Stellen Sie die Python 3-Funktion mit Serverless Framework unter AWS Lambda bereit
Erstellen Sie in Docker eine Ebene für AWS Lambda Python
[AWS] Spielen mit Schrittfunktionen (SAM + Lambda) Teil 1 (Basic)
Ich möchte Lambda mit Python auf Mac AWS!
Verwalten Sie die Aufbewahrung von Amazon CloudWatch-Protokollgruppen mit AWS Lambda
Machen Sie mit AWS Lambda und Python gewöhnliche Tweets flottenartig
[AWS] Spielen mit Schrittfunktionen (SAM + Lambda) Teil 2 (Parameter)