J'ai essayé de créer un outil de création de modèle pour CloudFormation en utilisant la troposphère. De plus, en exécutant l'outil créé sur Lambda, j'ai essayé de créer un modèle simplement en plaçant la feuille de paramètres sur S3.
Récemment, j'ai eu l'opportunité de toucher CloudFormation dans mon entreprise. Je pense que le goulot d'étranglement dans l'utilisation de CloudFormation est le fichier au format JSON.
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"
}
}
}
Le simple fait de créer deux VPC ressemble à ceci, donc je pense que c'est assez artisanal d'écrire ceci à la main.
troposphere est un outil pour créer un tel fichier au format JSON en l'écrivant en Python. https://github.com/cloudtools/troposphere Le code ci-dessus peut également être écrit d'une manière facile à lire comme suit en l'écrivant en utilisant tropical.
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)
L'utilisation de base est de décrire le nom et la description de la version avec add_version et add_description, puis d'ajouter plus de ressources à créer avec add_resource. Ce n'est pas beaucoup plus facile à lire, mais je pense que c'est un peu mieux que de l'écrire au format JSON. En outre, non seulement c'est plus facile à voir, mais le fait est que vous pouvez utiliser Python pour et si des instructions. Il est possible de décrire facilement une grande quantité de ressources en décrivant en passant plusieurs blocs CIDR et noms sous forme de tableau.
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)
À propos, dans l'état ci-dessus, les valeurs de réglage telles que le bloc CIDR et le nom seront écrites dans le script, mais cela est difficile à utiliser. Lisons les paramètres de l'extérieur et stockons-les dans un tableau afin qu'ils puissent être utilisés. Dans ce cas, deux types d'informations sont nécessaires en tant que paramètres (bloc CIDR, nom), créez donc une feuille de paramètres comme indiqué ci-dessous et enregistrez-la sous forme de fichier texte. 1ère ligne 10.1.0.0/16, 10.2.0.0/16 Test de 2e ligne1, test2
Après avoir créé un fichier texte, ouvrez et chargez d'abord ce fichier texte.
python
f = open('test.txt')
test = f.read()
f.close
Les données sont maintenant stockées dans le test. Cependant, dans cet état, la première ligne et la deuxième ligne ne sont pas séparées. Utilisez donc des lignes de fractionnement pour stocker chaque ligne sous forme de tableau.
python
test_list= test.splitlines()
Cela créera un tableau test_list avec chaque ligne comme élément. ["10.1.0.0/16,10.2.0.0/16","test1,test2"] De plus, ici, split est utilisé pour créer un tableau de chaque paramètre.
python
VPC_CidrBlockList = test_list[0].split(',')
VPC_TagNameList = test_list[1].split(',')
Vous avez maintenant créé un tableau de paramètres. Si vous intégrez ces opérations et modifiez le script précédent, ce sera comme suit.
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)
Vous pouvez désormais créer plusieurs VPC en fonction des paramètres répertoriés dans la feuille de paramètres.
La partie de base de l'utilisation de Lambda reste la même, mais le processus d'acquisition de la feuille de paramètres du compartiment S3 et le processus de téléchargement du modèle créé dans le compartiment S3 ont été ajoutés.
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'Créer un 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)
Vous pouvez également le définir de manière plus flexible en modifiant les éléments à définir en tant que variables (tels que "EnableDnsHostnames" dans VPC). De plus, si vous décrivez d'autres ressources de cette manière, vous pouvez créer automatiquement des modèles tels que des sous-réseaux et des groupes de sécurité ainsi que des VPC.