troposphereによるCloudFormationテンプレートの作成

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

troposphereというCloudFormationのテンプレートを作成するライブラリを見つけたので使ってみました。以下、troposphereの紹介と使ってみた実例です。

troposphereについて

CloudFormationテンプレートの定義を、Pythonで行うためのDSLと言えると思います。以下、公式ページからの抜粋です。

The troposphere library allows for easier creation of the AWS CloudFormation JSON by writing Python code to describe the AWS resources.

troposphere

サポートしているAWSのリソースも、公式ページから抜粋すると以下のように充実している印象です。

  • AWS::AutoScaling
  • AWS::CloudFormation
  • AWS::CloudFront
  • AWS::CloudTrail
  • AWS::CloudWatch
  • AWS::CodeDeploy
  • AWS::CodePipeline
  • AWS::Config
  • AWS::DirectoryService
  • AWS::DynamoDB
  • AWS::EC2
  • AWS::ECR
  • AWS::ECS
  • AWS::ElastiCache
  • AWS::ElasticBeanstalk
  • AWS::ElasticLoadBalancing
  • AWS::Elasticsearch
  • AWS::EMR
  • AWS::IAM
  • AWS::KINESIS
  • AWS::KinesisFirehose
  • AWS::KMS
  • AWS::Lambda
  • AWS::Logs
  • AWS::OPSWORKS
  • AWS::RDS
  • AWS::REDSHIFT
  • AWS::Route53
  • AWS::S3
  • AWS::SDB
  • AWS::SNS
  • AWS::SQS
  • AWS::SSM
  • AWS::WorkSpaces

使用例と手順

先の公式ページにも使用例はあったのですが、それとは別に私もテンプレートを作成してみました。内容はS3のバケットを作成するだけのものです。以下、その手順となります。尚、Python 2.7.11で実行してみました。

1.作業環境の作成

pyenv・virtualenvを使い、今回の作業を行う環境を作成します。ターミナルで作業用のディレクトリに移動し、以下のコマンドを実行します。

$ pyenv local 2.7.11
$ virtualenv venv
$ . venv/bin/activate
$ pip install troposphere

2.サンプルのコピー

CloudFormationテンプレートを出力するためのPythonのソースを一から作成してもいいのですが、GitHub上にはサンプルがあるので、それをコピーしました。以下、サンプルがあるGitHubのリンクです。

troposphere/examples

今回はこれらの中から「S3_Bucket.py」をコピーしました。

3.サンプルの編集

上記でコピーしたサンプルを元に、今回作成したバケットの定義を記述します。バケットは以下のような定義としました。

バケット名 troposhere-sample-bucket
アクセス制限 Private

Pythonのコードは以下のようになりました。

from troposphere import Output, Ref, Template
from troposphere.s3 import Bucket, Private


t = Template()

t.add_description(
    "Templete to create bucket."
)

s3bucket = t.add_resource(Bucket("S3Bucket", BucketName="troposhere-sample-bucket", AccessControl=Private))

t.add_output(Output(
    "BucketName",
    Value=Ref(s3bucket),
    Description="Created a Bucket with troposhere."
))

print(t.to_json())

サンプルから主に変更したところは、11行目で「BucketName」を追加したことと、「AccessControl」をPrivateにしたことです。これらを変更にあたり、値の指定方法などはtroposphereライブラリのソースを直接参考しました。具体的には、2行目でインポートしている「〜/venv/lib/python2.7/site-packages/troposphere/s3.py」のBucketクラスを見ると、どのような値が指定できるのかを理解できました。

(中略)
class Bucket(AWSObject):
    resource_type = "AWS::S3::Bucket"

    props = {
        'AccessControl': (basestring, False),
        'BucketName': (s3_bucket_name, False),
        'CorsConfiguration': (CorsConfiguration, False),
        'LifecycleConfiguration': (LifecycleConfiguration, False),
        'LoggingConfiguration': (LoggingConfiguration, False),
        'NotificationConfiguration': (NotificationConfiguration, False),
        'ReplicationConfiguration': (ReplicationConfiguration, False),
        'Tags': (Tags, False),
        'WebsiteConfiguration': (WebsiteConfiguration, False),
        'VersioningConfiguration': (VersioningConfiguration, False)
    }

    access_control_types = [
        Private,
        PublicRead,
        PublicReadWrite,
        AuthenticatedRead,
        BucketOwnerRead,
        BucketOwnerFullControl,
        LogDeliveryWrite,
    ]
(以下略)

s3.pyより抜粋

4.テンプレートの出力

Pythonのソースは作成できたので、テンプレートを出力してみます。先のPythonのソースをそのまま実行するだけです。

$ python S3_Bucket.py
{
    "Description": "Templete to create bucket.",
    "Outputs": {
        "BucketName": {
            "Description": "Created a Bucket with troposhere.",
            "Value": {
                "Ref": "S3Bucket"
            }
        }
    },
    "Resources": {
        "S3Bucket": {
            "Properties": {
                "AccessControl": "Private",
                "BucketName": "troposhere-sample-bucket"
            },
            "Type": "AWS::S3::Bucket"
        }
    }
}

テンプレートが標準出力されました。このテンプレートをCloudFormationで使用するため、パイプでjsonファイルに出力します。

python S3_Bucket.py > S3_Bucket.json

尚、テンプレートとしての定義に誤りがあれば、Pythonのソースの実行時にエラーとして出力してくれることもあるようです。以下、バケット名に「_」(アンダーバー)を使用した場合のエラーメッセージです。

$ python S3_Bucket.py
(中略)
ValueError: troposhere_sample-bucket is not a valid s3 bucket name

テンプレートの実行

CloudFormationテンプレートは作成できたので、実際に実行してみました。これについてはマネージメントコンソール上でテンプレートを指定しての、通常の手順となります。

troposphere-create-cloudformation-template_web

このようにテンプレートを指定したCloudFormation Stackを実行すると、以下の様なバケットが作成されました。

troposphere-create-cloudformation-template_bucket

まとめ

troposphereを使い、CloudFormationテンプレートを作成して実行してみました。非常に簡単な例ですが、作成して以下の点が気に入りました。

  • ソースでAWSリソースを定義できること
  • そのサンプルがあること
  • プロパティの指定方法をライブラリのソースから解析できること

またPythonで記述するため、作成したテンプレートを直接CloudFormationに渡すようなソースを追加すれば、コマンド1つでリリースの作成までできるかもしれません。

何かの時に参考になれば幸いです。