Fix merge conflicts. Add basic cloudformation support. Closes #111.
This commit is contained in:
parent
069c48b43a
commit
ef876dd27e
28 changed files with 2473 additions and 11 deletions
0
tests/test_cloudformation/__init__.py
Normal file
0
tests/test_cloudformation/__init__.py
Normal file
0
tests/test_cloudformation/fixtures/__init__.py
Normal file
0
tests/test_cloudformation/fixtures/__init__.py
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
template = {
|
||||
"Description": "AWS CloudFormation Sample Template Gollum_Single_Instance_With_EBS_Volume: Gollum is a simple wiki system built on top of Git that powers GitHub Wikis. This template installs a Gollum Wiki stack on a single EC2 instance with an EBS volume for storage and demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary at instance launch time. **WARNING** This template creates an Amazon EC2 instance and an EBS volume. You will be billed for the AWS resources used if you create a stack from this template.",
|
||||
"Parameters": {
|
||||
"SSHLocation": {
|
||||
"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x.",
|
||||
"Description": "The IP address range that can be used to SSH to the EC2 instances",
|
||||
"Default": "0.0.0.0/0",
|
||||
"MinLength": "9",
|
||||
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
|
||||
"MaxLength": "18",
|
||||
"Type": "String"
|
||||
},
|
||||
"KeyName": {
|
||||
"Type": "String",
|
||||
"Description": "Name of an existing EC2 KeyPair to enable SSH access to the instances",
|
||||
"MinLength": "1",
|
||||
"AllowedPattern": "[\\x20-\\x7E]*",
|
||||
"MaxLength": "255",
|
||||
"ConstraintDescription": "can contain only ASCII characters."
|
||||
},
|
||||
"InstanceType": {
|
||||
"Default": "m1.small",
|
||||
"ConstraintDescription": "must be a valid EC2 instance type.",
|
||||
"Type": "String",
|
||||
"Description": "WebServer EC2 instance type",
|
||||
"AllowedValues": [
|
||||
"t1.micro",
|
||||
"m1.small",
|
||||
"m1.medium",
|
||||
"m1.large",
|
||||
"m1.xlarge",
|
||||
"m2.xlarge",
|
||||
"m2.2xlarge",
|
||||
"m2.4xlarge",
|
||||
"m3.xlarge",
|
||||
"m3.2xlarge",
|
||||
"c1.medium",
|
||||
"c1.xlarge",
|
||||
"cc1.4xlarge",
|
||||
"cc2.8xlarge",
|
||||
"cg1.4xlarge"
|
||||
]
|
||||
},
|
||||
"VolumeSize": {
|
||||
"Description": "WebServer EC2 instance type",
|
||||
"Default": "5",
|
||||
"Type": "Number",
|
||||
"MaxValue": "1024",
|
||||
"MinValue": "5",
|
||||
"ConstraintDescription": "must be between 5 and 1024 Gb."
|
||||
}
|
||||
},
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Outputs": {
|
||||
"WebsiteURL": {
|
||||
"Description": "URL for Gollum wiki",
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"http://",
|
||||
{
|
||||
"Fn::GetAtt": [
|
||||
"WebServer",
|
||||
"PublicDnsName"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Resources": {
|
||||
"WebServerSecurityGroup": {
|
||||
"Type": "AWS::EC2::SecurityGroup",
|
||||
"Properties": {
|
||||
"SecurityGroupIngress": [
|
||||
{
|
||||
"ToPort": "80",
|
||||
"IpProtocol": "tcp",
|
||||
"CidrIp": "0.0.0.0/0",
|
||||
"FromPort": "80"
|
||||
},
|
||||
{
|
||||
"ToPort": "22",
|
||||
"IpProtocol": "tcp",
|
||||
"CidrIp": {
|
||||
"Ref": "SSHLocation"
|
||||
},
|
||||
"FromPort": "22"
|
||||
}
|
||||
],
|
||||
"GroupDescription": "Enable SSH access and HTTP access on the inbound port"
|
||||
}
|
||||
},
|
||||
"WebServer": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
"Properties": {
|
||||
"UserData": {
|
||||
"Fn::Base64": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"#!/bin/bash -v\n",
|
||||
"yum update -y aws-cfn-bootstrap\n",
|
||||
"# Helper function\n",
|
||||
"function error_exit\n",
|
||||
"{\n",
|
||||
" /opt/aws/bin/cfn-signal -e 1 -r \"$1\" '",
|
||||
{
|
||||
"Ref": "WaitHandle"
|
||||
},
|
||||
"'\n",
|
||||
" exit 1\n",
|
||||
"}\n",
|
||||
"# Install Rails packages\n",
|
||||
"/opt/aws/bin/cfn-init -s ",
|
||||
{
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
" -r WebServer ",
|
||||
" --region ",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
" || error_exit 'Failed to run cfn-init'\n",
|
||||
"# Wait for the EBS volume to show up\n",
|
||||
"while [ ! -e /dev/sdh ]; do echo Waiting for EBS volume to attach; sleep 5; done\n",
|
||||
"# Format the EBS volume and mount it\n",
|
||||
"mkdir /var/wikidata\n",
|
||||
"/sbin/mkfs -t ext3 /dev/sdh1\n",
|
||||
"mount /dev/sdh1 /var/wikidata\n",
|
||||
"# Initialize the wiki and fire up the server\n",
|
||||
"cd /var/wikidata\n",
|
||||
"git init\n",
|
||||
"gollum --port 80 --host 0.0.0.0 &\n",
|
||||
"# If all is well so signal success\n",
|
||||
"/opt/aws/bin/cfn-signal -e $? -r \"Rails application setup complete\" '",
|
||||
{
|
||||
"Ref": "WaitHandle"
|
||||
},
|
||||
"'\n"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"KeyName": {
|
||||
"Ref": "KeyName"
|
||||
},
|
||||
"SecurityGroups": [
|
||||
{
|
||||
"Ref": "WebServerSecurityGroup"
|
||||
}
|
||||
],
|
||||
"InstanceType": {
|
||||
"Ref": "InstanceType"
|
||||
},
|
||||
"ImageId": {
|
||||
"Fn::FindInMap": [
|
||||
"AWSRegionArch2AMI",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
{
|
||||
"Fn::FindInMap": [
|
||||
"AWSInstanceType2Arch",
|
||||
{
|
||||
"Ref": "InstanceType"
|
||||
},
|
||||
"Arch"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Metadata": {
|
||||
"AWS::CloudFormation::Init": {
|
||||
"config": {
|
||||
"packages": {
|
||||
"rubygems": {
|
||||
"nokogiri": [
|
||||
"1.5.10"
|
||||
],
|
||||
"rdiscount": [],
|
||||
"gollum": [
|
||||
"1.1.1"
|
||||
]
|
||||
},
|
||||
"yum": {
|
||||
"libxslt-devel": [],
|
||||
"gcc": [],
|
||||
"git": [],
|
||||
"rubygems": [],
|
||||
"ruby-devel": [],
|
||||
"ruby-rdoc": [],
|
||||
"make": [],
|
||||
"libxml2-devel": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"DataVolume": {
|
||||
"Type": "AWS::EC2::Volume",
|
||||
"Properties": {
|
||||
"Tags": [
|
||||
{
|
||||
"Value": "Gollum Data Volume",
|
||||
"Key": "Usage"
|
||||
}
|
||||
],
|
||||
"AvailabilityZone": {
|
||||
"Fn::GetAtt": [
|
||||
"WebServer",
|
||||
"AvailabilityZone"
|
||||
]
|
||||
},
|
||||
"Size": "100",
|
||||
}
|
||||
},
|
||||
"MountPoint": {
|
||||
"Type": "AWS::EC2::VolumeAttachment",
|
||||
"Properties": {
|
||||
"InstanceId": {
|
||||
"Ref": "WebServer"
|
||||
},
|
||||
"Device": "/dev/sdh",
|
||||
"VolumeId": {
|
||||
"Ref": "DataVolume"
|
||||
}
|
||||
}
|
||||
},
|
||||
"WaitCondition": {
|
||||
"DependsOn": "MountPoint",
|
||||
"Type": "AWS::CloudFormation::WaitCondition",
|
||||
"Properties": {
|
||||
"Handle": {
|
||||
"Ref": "WaitHandle"
|
||||
},
|
||||
"Timeout": "300"
|
||||
},
|
||||
"Metadata": {
|
||||
"Comment1": "Note that the WaitCondition is dependent on the volume mount point allowing the volume to be created and attached to the EC2 instance",
|
||||
"Comment2": "The instance bootstrap script waits for the volume to be attached to the instance prior to installing Gollum and signalling completion"
|
||||
}
|
||||
},
|
||||
"WaitHandle": {
|
||||
"Type": "AWS::CloudFormation::WaitConditionHandle"
|
||||
}
|
||||
},
|
||||
"Mappings": {
|
||||
"AWSInstanceType2Arch": {
|
||||
"m3.2xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m2.2xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m1.small": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"c1.medium": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"cg1.4xlarge": {
|
||||
"Arch": "64HVM"
|
||||
},
|
||||
"m2.xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"t1.micro": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"cc1.4xlarge": {
|
||||
"Arch": "64HVM"
|
||||
},
|
||||
"m1.medium": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"cc2.8xlarge": {
|
||||
"Arch": "64HVM"
|
||||
},
|
||||
"m1.large": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m1.xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m2.4xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"c1.xlarge": {
|
||||
"Arch": "64"
|
||||
},
|
||||
"m3.xlarge": {
|
||||
"Arch": "64"
|
||||
}
|
||||
},
|
||||
"AWSRegionArch2AMI": {
|
||||
"ap-southeast-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-b4b0cae6",
|
||||
"64": "ami-beb0caec"
|
||||
},
|
||||
"ap-southeast-2": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-b3990e89",
|
||||
"64": "ami-bd990e87"
|
||||
},
|
||||
"us-west-2": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-38fe7308",
|
||||
"64": "ami-30fe7300"
|
||||
},
|
||||
"us-east-1": {
|
||||
"64HVM": "ami-0da96764",
|
||||
"32": "ami-31814f58",
|
||||
"64": "ami-1b814f72"
|
||||
},
|
||||
"ap-northeast-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-0644f007",
|
||||
"64": "ami-0a44f00b"
|
||||
},
|
||||
"us-west-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-11d68a54",
|
||||
"64": "ami-1bd68a5e"
|
||||
},
|
||||
"eu-west-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-973b06e3",
|
||||
"64": "ami-953b06e1"
|
||||
},
|
||||
"sa-east-1": {
|
||||
"64HVM": "NOT_YET_SUPPORTED",
|
||||
"32": "ami-3e3be423",
|
||||
"64": "ami-3c3be421"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,402 @@
|
|||
template = {
|
||||
"Description": "AWS CloudFormation Sample Template vpc_single_instance_in_subnet.template: Sample template showing how to create a VPC and add an EC2 instance with an Elastic IP address and a security group. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.",
|
||||
"Parameters": {
|
||||
"SSHLocation": {
|
||||
"ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x.",
|
||||
"Description": " The IP address range that can be used to SSH to the EC2 instances",
|
||||
"Default": "0.0.0.0/0",
|
||||
"MinLength": "9",
|
||||
"AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
|
||||
"MaxLength": "18",
|
||||
"Type": "String"
|
||||
},
|
||||
"KeyName": {
|
||||
"Type": "String",
|
||||
"Description": "Name of an existing EC2 KeyPair to enable SSH access to the instance",
|
||||
"MinLength": "1",
|
||||
"AllowedPattern": "[\\x20-\\x7E]*",
|
||||
"MaxLength": "255",
|
||||
"ConstraintDescription": "can contain only ASCII characters."
|
||||
},
|
||||
"InstanceType": {
|
||||
"Default": "m1.small",
|
||||
"ConstraintDescription": "must be a valid EC2 instance type.",
|
||||
"Type": "String",
|
||||
"Description": "WebServer EC2 instance type",
|
||||
"AllowedValues": [
|
||||
"t1.micro",
|
||||
"m1.small",
|
||||
"m1.medium",
|
||||
"m1.large",
|
||||
"m1.xlarge",
|
||||
"m2.xlarge",
|
||||
"m2.2xlarge",
|
||||
"m2.4xlarge",
|
||||
"m3.xlarge",
|
||||
"m3.2xlarge",
|
||||
"c1.medium",
|
||||
"c1.xlarge",
|
||||
"cc1.4xlarge",
|
||||
"cc2.8xlarge",
|
||||
"cg1.4xlarge"
|
||||
]
|
||||
}
|
||||
},
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Outputs": {
|
||||
"URL": {
|
||||
"Description": "Newly created application URL",
|
||||
"Value": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"http://",
|
||||
{
|
||||
"Fn::GetAtt": [
|
||||
"WebServerInstance",
|
||||
"PublicIp"
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"Resources": {
|
||||
"Subnet": {
|
||||
"Type": "AWS::EC2::Subnet",
|
||||
"Properties": {
|
||||
"VpcId": {
|
||||
"Ref": "VPC"
|
||||
},
|
||||
"CidrBlock": "10.0.0.0/24",
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"WebServerWaitHandle": {
|
||||
"Type": "AWS::CloudFormation::WaitConditionHandle"
|
||||
},
|
||||
"Route": {
|
||||
"Type": "AWS::EC2::Route",
|
||||
"Properties": {
|
||||
"GatewayId": {
|
||||
"Ref": "InternetGateway"
|
||||
},
|
||||
"DestinationCidrBlock": "0.0.0.0/0",
|
||||
"RouteTableId": {
|
||||
"Ref": "RouteTable"
|
||||
}
|
||||
},
|
||||
"DependsOn": "AttachGateway"
|
||||
},
|
||||
"SubnetRouteTableAssociation": {
|
||||
"Type": "AWS::EC2::SubnetRouteTableAssociation",
|
||||
"Properties": {
|
||||
"SubnetId": {
|
||||
"Ref": "Subnet"
|
||||
},
|
||||
"RouteTableId": {
|
||||
"Ref": "RouteTable"
|
||||
}
|
||||
}
|
||||
},
|
||||
"InternetGateway": {
|
||||
"Type": "AWS::EC2::InternetGateway",
|
||||
"Properties": {
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"RouteTable": {
|
||||
"Type": "AWS::EC2::RouteTable",
|
||||
"Properties": {
|
||||
"VpcId": {
|
||||
"Ref": "VPC"
|
||||
},
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"WebServerWaitCondition": {
|
||||
"Type": "AWS::CloudFormation::WaitCondition",
|
||||
"Properties": {
|
||||
"Handle": {
|
||||
"Ref": "WebServerWaitHandle"
|
||||
},
|
||||
"Timeout": "300"
|
||||
},
|
||||
"DependsOn": "WebServerInstance"
|
||||
},
|
||||
"VPC": {
|
||||
"Type": "AWS::EC2::VPC",
|
||||
"Properties": {
|
||||
"CidrBlock": "10.0.0.0/16",
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"InstanceSecurityGroup": {
|
||||
"Type": "AWS::EC2::SecurityGroup",
|
||||
"Properties": {
|
||||
"SecurityGroupIngress": [
|
||||
{
|
||||
"ToPort": "22",
|
||||
"IpProtocol": "tcp",
|
||||
"CidrIp": {
|
||||
"Ref": "SSHLocation"
|
||||
},
|
||||
"FromPort": "22"
|
||||
},
|
||||
{
|
||||
"ToPort": "80",
|
||||
"IpProtocol": "tcp",
|
||||
"CidrIp": "0.0.0.0/0",
|
||||
"FromPort": "80"
|
||||
}
|
||||
],
|
||||
"VpcId": {
|
||||
"Ref": "VPC"
|
||||
},
|
||||
"GroupDescription": "Enable SSH access via port 22"
|
||||
}
|
||||
},
|
||||
"WebServerInstance": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
"Properties": {
|
||||
"UserData": {
|
||||
"Fn::Base64": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"#!/bin/bash\n",
|
||||
"yum update -y aws-cfn-bootstrap\n",
|
||||
"# Helper function\n",
|
||||
"function error_exit\n",
|
||||
"{\n",
|
||||
" /opt/aws/bin/cfn-signal -e 1 -r \"$1\" '",
|
||||
{
|
||||
"Ref": "WebServerWaitHandle"
|
||||
},
|
||||
"'\n",
|
||||
" exit 1\n",
|
||||
"}\n",
|
||||
"# Install the simple web page\n",
|
||||
"/opt/aws/bin/cfn-init -s ",
|
||||
{
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
" -r WebServerInstance ",
|
||||
" --region ",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
" || error_exit 'Failed to run cfn-init'\n",
|
||||
"# Start up the cfn-hup daemon to listen for changes to the Web Server metadata\n",
|
||||
"/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n",
|
||||
"# All done so signal success\n",
|
||||
"/opt/aws/bin/cfn-signal -e 0 -r \"WebServer setup complete\" '",
|
||||
{
|
||||
"Ref": "WebServerWaitHandle"
|
||||
},
|
||||
"'\n"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"Tags": [
|
||||
{
|
||||
"Value": {
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"Key": "Application"
|
||||
}
|
||||
],
|
||||
"SecurityGroupIds": [
|
||||
{
|
||||
"Ref": "InstanceSecurityGroup"
|
||||
}
|
||||
],
|
||||
"KeyName": {
|
||||
"Ref": "KeyName"
|
||||
},
|
||||
"SubnetId": {
|
||||
"Ref": "Subnet"
|
||||
},
|
||||
"ImageId": {
|
||||
"Fn::FindInMap": [
|
||||
"RegionMap",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
"AMI"
|
||||
]
|
||||
},
|
||||
"InstanceType": {
|
||||
"Ref": "InstanceType"
|
||||
}
|
||||
},
|
||||
"Metadata": {
|
||||
"Comment": "Install a simple PHP application",
|
||||
"AWS::CloudFormation::Init": {
|
||||
"config": {
|
||||
"files": {
|
||||
"/etc/cfn/cfn-hup.conf": {
|
||||
"content": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"[main]\n",
|
||||
"stack=",
|
||||
{
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
"\n",
|
||||
"region=",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
"\n"
|
||||
]
|
||||
]
|
||||
},
|
||||
"owner": "root",
|
||||
"group": "root",
|
||||
"mode": "000400"
|
||||
},
|
||||
"/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
|
||||
"content": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"[cfn-auto-reloader-hook]\n",
|
||||
"triggers=post.update\n",
|
||||
"path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n",
|
||||
"action=/opt/aws/bin/cfn-init -s ",
|
||||
{
|
||||
"Ref": "AWS::StackId"
|
||||
},
|
||||
" -r WebServerInstance ",
|
||||
" --region ",
|
||||
{
|
||||
"Ref": "AWS::Region"
|
||||
},
|
||||
"\n",
|
||||
"runas=root\n"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"/var/www/html/index.php": {
|
||||
"content": {
|
||||
"Fn::Join": [
|
||||
"",
|
||||
[
|
||||
"<?php\n",
|
||||
"echo '<h1>AWS CloudFormation sample PHP application</h1>';\n",
|
||||
"?>\n"
|
||||
]
|
||||
]
|
||||
},
|
||||
"owner": "apache",
|
||||
"group": "apache",
|
||||
"mode": "000644"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"sysvinit": {
|
||||
"httpd": {
|
||||
"ensureRunning": "true",
|
||||
"enabled": "true"
|
||||
},
|
||||
"sendmail": {
|
||||
"ensureRunning": "false",
|
||||
"enabled": "false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"packages": {
|
||||
"yum": {
|
||||
"httpd": [],
|
||||
"php": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"IPAddress": {
|
||||
"Type": "AWS::EC2::EIP",
|
||||
"Properties": {
|
||||
"InstanceId": {
|
||||
"Ref": "WebServerInstance"
|
||||
},
|
||||
"Domain": "vpc"
|
||||
},
|
||||
"DependsOn": "AttachGateway"
|
||||
},
|
||||
"AttachGateway": {
|
||||
"Type": "AWS::EC2::VPCGatewayAttachment",
|
||||
"Properties": {
|
||||
"VpcId": {
|
||||
"Ref": "VPC"
|
||||
},
|
||||
"InternetGatewayId": {
|
||||
"Ref": "InternetGateway"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Mappings": {
|
||||
"RegionMap": {
|
||||
"ap-southeast-1": {
|
||||
"AMI": "ami-74dda626"
|
||||
},
|
||||
"ap-southeast-2": {
|
||||
"AMI": "ami-b3990e89"
|
||||
},
|
||||
"us-west-2": {
|
||||
"AMI": "ami-16fd7026"
|
||||
},
|
||||
"us-east-1": {
|
||||
"AMI": "ami-7f418316"
|
||||
},
|
||||
"ap-northeast-1": {
|
||||
"AMI": "ami-dcfa4edd"
|
||||
},
|
||||
"us-west-1": {
|
||||
"AMI": "ami-951945d0"
|
||||
},
|
||||
"eu-west-1": {
|
||||
"AMI": "ami-24506250"
|
||||
},
|
||||
"sa-east-1": {
|
||||
"AMI": "ami-3e3be423"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
115
tests/test_cloudformation/test_cloudformation_stack_crud.py
Normal file
115
tests/test_cloudformation/test_cloudformation_stack_crud.py
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
import json
|
||||
|
||||
import boto
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_cloudformation
|
||||
|
||||
dummy_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 1",
|
||||
"Resources": {},
|
||||
}
|
||||
|
||||
dummy_template2 = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 2",
|
||||
"Resources": {},
|
||||
}
|
||||
|
||||
dummy_template_json = json.dumps(dummy_template)
|
||||
dummy_template_json2 = json.dumps(dummy_template2)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_create_stack():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
stack.stack_name.should.equal('test_stack')
|
||||
stack.get_template().should.equal(dummy_template)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_describe_stack_by_name():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
|
||||
stack = conn.describe_stacks("test_stack")[0]
|
||||
stack.stack_name.should.equal('test_stack')
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_get_template_by_name():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
|
||||
template = conn.get_template("test_stack")
|
||||
template.should.equal(dummy_template)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_list_stacks():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
conn.create_stack(
|
||||
"test_stack2",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
|
||||
stacks = conn.list_stacks()
|
||||
stacks.should.have.length_of(2)
|
||||
stacks[0].template_description.should.equal("Stack 1")
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_delete_stack_by_name():
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
|
||||
conn.list_stacks().should.have.length_of(1)
|
||||
conn.delete_stack("test_stack")
|
||||
conn.list_stacks().should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_delete_stack_by_id():
|
||||
conn = boto.connect_cloudformation()
|
||||
stack_id = conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=dummy_template_json,
|
||||
)
|
||||
|
||||
conn.list_stacks().should.have.length_of(1)
|
||||
conn.delete_stack(stack_id)
|
||||
conn.list_stacks().should.have.length_of(0)
|
||||
|
||||
|
||||
# @mock_cloudformation
|
||||
# def test_update_stack():
|
||||
# conn = boto.connect_cloudformation()
|
||||
# conn.create_stack(
|
||||
# "test_stack",
|
||||
# template_body=dummy_template_json,
|
||||
# )
|
||||
|
||||
# conn.update_stack("test_stack", dummy_template_json2)
|
||||
|
||||
# stack = conn.describe_stacks()[0]
|
||||
# stack.get_template().should.equal(dummy_template2)
|
||||
|
|
@ -0,0 +1,473 @@
|
|||
import json
|
||||
|
||||
import boto
|
||||
import sure # noqa
|
||||
|
||||
from moto import (
|
||||
mock_autoscaling,
|
||||
mock_cloudformation,
|
||||
mock_ec2,
|
||||
mock_elb,
|
||||
mock_iam,
|
||||
)
|
||||
|
||||
from .fixtures import single_instance_with_ebs_volume, vpc_single_instance_in_subnet
|
||||
|
||||
|
||||
@mock_cloudformation()
|
||||
def test_stack_sqs_integration():
|
||||
sqs_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"QueueGroup": {
|
||||
|
||||
"Type": "AWS::SQS::Queue",
|
||||
"Properties": {
|
||||
"QueueName": "my-queue",
|
||||
"VisibilityTimeout": 60,
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
sqs_template_json = json.dumps(sqs_template)
|
||||
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=sqs_template_json,
|
||||
)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
queue = stack.describe_resources()[0]
|
||||
queue.resource_type.should.equal('AWS::SQS::Queue')
|
||||
queue.logical_resource_id.should.equal("QueueGroup")
|
||||
queue.physical_resource_id.should.equal("my-queue")
|
||||
|
||||
|
||||
@mock_ec2()
|
||||
@mock_cloudformation()
|
||||
def test_stack_ec2_integration():
|
||||
ec2_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"WebServerGroup": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
"Properties": {
|
||||
"ImageId": "ami-1234abcd",
|
||||
"UserData": "some user data",
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
ec2_template_json = json.dumps(ec2_template)
|
||||
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"ec2_stack",
|
||||
template_body=ec2_template_json,
|
||||
)
|
||||
|
||||
ec2_conn = boto.connect_ec2()
|
||||
reservation = ec2_conn.get_all_instances()[0]
|
||||
ec2_instance = reservation.instances[0]
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
instance = stack.describe_resources()[0]
|
||||
instance.resource_type.should.equal('AWS::EC2::Instance')
|
||||
instance.logical_resource_id.should.equal("WebServerGroup")
|
||||
instance.physical_resource_id.should.equal(ec2_instance.id)
|
||||
|
||||
|
||||
@mock_ec2()
|
||||
@mock_elb()
|
||||
@mock_cloudformation()
|
||||
def test_stack_elb_integration_with_attached_ec2_instances():
|
||||
elb_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"MyELB": {
|
||||
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
|
||||
"Instances": [{"Ref": "Ec2Instance1"}],
|
||||
"Properties": {
|
||||
"LoadBalancerName": "test-elb",
|
||||
"AvailabilityZones": ['us-east1'],
|
||||
}
|
||||
},
|
||||
"Ec2Instance1": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
"Properties": {
|
||||
"ImageId": "ami-1234abcd",
|
||||
"UserData": "some user data",
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
elb_template_json = json.dumps(elb_template)
|
||||
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"elb_stack",
|
||||
template_body=elb_template_json,
|
||||
)
|
||||
|
||||
elb_conn = boto.connect_elb()
|
||||
load_balancer = elb_conn.get_all_load_balancers()[0]
|
||||
|
||||
ec2_conn = boto.connect_ec2()
|
||||
reservation = ec2_conn.get_all_instances()[0]
|
||||
ec2_instance = reservation.instances[0]
|
||||
instance_id = ec2_instance.id
|
||||
|
||||
load_balancer.instances[0].id.should.equal(ec2_instance.id)
|
||||
list(load_balancer.availability_zones).should.equal(['us-east1'])
|
||||
load_balancer_name = load_balancer.name
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
stack_resources = stack.describe_resources()
|
||||
stack_resources.should.have.length_of(2)
|
||||
for resource in stack_resources:
|
||||
if resource.resource_type == 'AWS::ElasticLoadBalancing::LoadBalancer':
|
||||
load_balancer = resource
|
||||
else:
|
||||
ec2_instance = resource
|
||||
|
||||
load_balancer.logical_resource_id.should.equal("MyELB")
|
||||
load_balancer.physical_resource_id.should.equal(load_balancer_name)
|
||||
ec2_instance.physical_resource_id.should.equal(instance_id)
|
||||
|
||||
|
||||
@mock_ec2()
|
||||
@mock_cloudformation()
|
||||
def test_stack_security_groups():
|
||||
security_group_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"my-security-group": {
|
||||
"Type": "AWS::EC2::SecurityGroup",
|
||||
"Properties": {
|
||||
"GroupDescription": "My other group",
|
||||
},
|
||||
},
|
||||
"Ec2Instance2": {
|
||||
"Type": "AWS::EC2::Instance",
|
||||
"Properties": {
|
||||
"SecurityGroups": [{"Ref": "InstanceSecurityGroup"}],
|
||||
"ImageId": "ami-1234abcd",
|
||||
}
|
||||
},
|
||||
"InstanceSecurityGroup": {
|
||||
"Type": "AWS::EC2::SecurityGroup",
|
||||
"Properties": {
|
||||
"GroupDescription": "My security group",
|
||||
"SecurityGroupIngress": [{
|
||||
"IpProtocol": "tcp",
|
||||
"FromPort": "22",
|
||||
"ToPort": "22",
|
||||
"CidrIp": "123.123.123.123/32",
|
||||
}, {
|
||||
"IpProtocol": "tcp",
|
||||
"FromPort": "80",
|
||||
"ToPort": "8000",
|
||||
"SourceSecurityGroupId": {"Ref": "my-security-group"},
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
security_group_template_json = json.dumps(security_group_template)
|
||||
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"security_group_stack",
|
||||
template_body=security_group_template_json,
|
||||
)
|
||||
|
||||
ec2_conn = boto.connect_ec2()
|
||||
security_groups = ec2_conn.get_all_security_groups()
|
||||
for group in security_groups:
|
||||
if group.name == "InstanceSecurityGroup":
|
||||
instance_group = group
|
||||
else:
|
||||
other_group = group
|
||||
|
||||
reservation = ec2_conn.get_all_instances()[0]
|
||||
ec2_instance = reservation.instances[0]
|
||||
|
||||
ec2_instance.groups[0].id.should.equal(instance_group.id)
|
||||
instance_group.description.should.equal("My security group")
|
||||
rule1, rule2 = instance_group.rules
|
||||
int(rule1.to_port).should.equal(22)
|
||||
int(rule1.from_port).should.equal(22)
|
||||
rule1.grants[0].cidr_ip.should.equal("123.123.123.123/32")
|
||||
rule1.ip_protocol.should.equal('tcp')
|
||||
|
||||
int(rule2.to_port).should.equal(8000)
|
||||
int(rule2.from_port).should.equal(80)
|
||||
rule2.ip_protocol.should.equal('tcp')
|
||||
rule2.grants[0].group_id.should.equal(other_group.id)
|
||||
|
||||
|
||||
@mock_autoscaling()
|
||||
@mock_elb()
|
||||
@mock_cloudformation()
|
||||
def test_autoscaling_group_with_elb():
|
||||
|
||||
web_setup_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
|
||||
"Resources": {
|
||||
"my-as-group": {
|
||||
"Type": "AWS::AutoScaling::AutoScalingGroup",
|
||||
"Properties": {
|
||||
"AvailabilityZones": ['us-east1'],
|
||||
"LaunchConfigurationName": {"Ref": "my-launch-config"},
|
||||
"MinSize": "2",
|
||||
"MaxSize": "2",
|
||||
"LoadBalancerNames": [{"Ref": "my-elb"}]
|
||||
},
|
||||
},
|
||||
|
||||
"my-launch-config": {
|
||||
"Type": "AWS::AutoScaling::LaunchConfiguration",
|
||||
"Properties": {
|
||||
"ImageId": "ami-1234abcd",
|
||||
"UserData": "some user data",
|
||||
}
|
||||
},
|
||||
|
||||
"my-elb": {
|
||||
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
|
||||
"Properties": {
|
||||
"AvailabilityZones": ['us-east1'],
|
||||
"Listeners": [{
|
||||
"LoadBalancerPort": "80",
|
||||
"InstancePort": "80",
|
||||
"Protocol": "HTTP"
|
||||
}],
|
||||
"HealthCheck": {
|
||||
"Target": "80",
|
||||
"HealthyThreshold": "3",
|
||||
"UnhealthyThreshold": "5",
|
||||
"Interval": "30",
|
||||
"Timeout": "5",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
web_setup_template_json = json.dumps(web_setup_template)
|
||||
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"web_stack",
|
||||
template_body=web_setup_template_json,
|
||||
)
|
||||
|
||||
autoscale_conn = boto.connect_autoscale()
|
||||
autoscale_group = autoscale_conn.get_all_groups()[0]
|
||||
autoscale_group.launch_config_name.should.equal("my-launch-config")
|
||||
autoscale_group.load_balancers[0].should.equal('my-elb')
|
||||
|
||||
# Confirm the Launch config was actually created
|
||||
autoscale_conn.get_all_launch_configurations().should.have.length_of(1)
|
||||
|
||||
# Confirm the ELB was actually created
|
||||
elb_conn = boto.connect_elb()
|
||||
elb_conn.get_all_load_balancers().should.have.length_of(1)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
resources = stack.describe_resources()
|
||||
as_group_resource = [resource for resource in resources if resource.resource_type == 'AWS::AutoScaling::AutoScalingGroup'][0]
|
||||
as_group_resource.physical_resource_id.should.equal("my-as-group")
|
||||
|
||||
launch_config_resource = [resource for resource in resources if resource.resource_type == 'AWS::AutoScaling::LaunchConfiguration'][0]
|
||||
launch_config_resource.physical_resource_id.should.equal("my-launch-config")
|
||||
|
||||
elb_resource = [resource for resource in resources if resource.resource_type == 'AWS::ElasticLoadBalancing::LoadBalancer'][0]
|
||||
elb_resource.physical_resource_id.should.equal("my-elb")
|
||||
|
||||
|
||||
@mock_ec2()
|
||||
@mock_cloudformation()
|
||||
def test_vpc_single_instance_in_subnet():
|
||||
|
||||
template_json = json.dumps(vpc_single_instance_in_subnet.template)
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=template_json,
|
||||
)
|
||||
|
||||
vpc_conn = boto.connect_vpc()
|
||||
vpc = vpc_conn.get_all_vpcs()[0]
|
||||
vpc.cidr_block.should.equal("10.0.0.0/16")
|
||||
|
||||
# Add this once we implement the endpoint
|
||||
# vpc_conn.get_all_internet_gateways().should.have.length_of(1)
|
||||
|
||||
subnet = vpc_conn.get_all_subnets()[0]
|
||||
subnet.vpc_id.should.equal(vpc.id)
|
||||
|
||||
ec2_conn = boto.connect_ec2()
|
||||
reservation = ec2_conn.get_all_instances()[0]
|
||||
instance = reservation.instances[0]
|
||||
# Check that the EIP is attached the the EC2 instance
|
||||
eip = ec2_conn.get_all_addresses()[0]
|
||||
eip.domain.should.equal('vpc')
|
||||
eip.instance_id.should.equal(instance.id)
|
||||
|
||||
security_group = ec2_conn.get_all_security_groups()[0]
|
||||
security_group.vpc_id.should.equal(vpc.id)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
resources = stack.describe_resources()
|
||||
vpc_resource = [resource for resource in resources if resource.resource_type == 'AWS::EC2::VPC'][0]
|
||||
vpc_resource.physical_resource_id.should.equal(vpc.id)
|
||||
|
||||
subnet_resource = [resource for resource in resources if resource.resource_type == 'AWS::EC2::Subnet'][0]
|
||||
subnet_resource.physical_resource_id.should.equal(subnet.id)
|
||||
|
||||
eip_resource = [resource for resource in resources if resource.resource_type == 'AWS::EC2::EIP'][0]
|
||||
eip_resource.physical_resource_id.should.equal(eip.allocation_id)
|
||||
|
||||
|
||||
@mock_autoscaling()
|
||||
@mock_iam()
|
||||
@mock_cloudformation()
|
||||
def test_iam_roles():
|
||||
iam_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
|
||||
"Resources": {
|
||||
|
||||
"my-launch-config": {
|
||||
"Properties": {
|
||||
"IamInstanceProfile": {"Ref": "my-instance-profile"},
|
||||
"ImageId": "ami-1234abcd",
|
||||
},
|
||||
"Type": "AWS::AutoScaling::LaunchConfiguration"
|
||||
},
|
||||
"my-instance-profile": {
|
||||
"Properties": {
|
||||
"Path": "my-path",
|
||||
"Roles": [{"Ref": "my-role"}],
|
||||
},
|
||||
"Type": "AWS::IAM::InstanceProfile"
|
||||
},
|
||||
"my-role": {
|
||||
"Properties": {
|
||||
"AssumeRolePolicyDocument": {
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"sts:AssumeRole"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"Service": [
|
||||
"ec2.amazonaws.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Path": "my-path",
|
||||
"Policies": [
|
||||
{
|
||||
"PolicyDocument": {
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"ec2:CreateTags",
|
||||
"ec2:DescribeInstances",
|
||||
"ec2:DescribeTags"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Resource": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"Version": "2012-10-17"
|
||||
},
|
||||
"PolicyName": "EC2_Tags"
|
||||
},
|
||||
{
|
||||
"PolicyDocument": {
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"sqs:*"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Resource": [
|
||||
"*"
|
||||
]
|
||||
}
|
||||
],
|
||||
"Version": "2012-10-17"
|
||||
},
|
||||
"PolicyName": "SQS"
|
||||
},
|
||||
]
|
||||
},
|
||||
"Type": "AWS::IAM::Role"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
iam_template_json = json.dumps(iam_template)
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=iam_template_json,
|
||||
)
|
||||
|
||||
iam_conn = boto.connect_iam()
|
||||
|
||||
role = iam_conn.get_role("my-role")
|
||||
role.role_name.should.equal("my-role")
|
||||
role.path.should.equal("my-path")
|
||||
|
||||
instance_profile = iam_conn.get_instance_profile("my-instance-profile")
|
||||
instance_profile.instance_profile_name.should.equal("my-instance-profile")
|
||||
instance_profile.path.should.equal("my-path")
|
||||
instance_profile.role_id.should.equal(role.role_id)
|
||||
|
||||
autoscale_conn = boto.connect_autoscale()
|
||||
launch_config = autoscale_conn.get_all_launch_configurations()[0]
|
||||
launch_config.instance_profile_name.should.equal("my-instance-profile")
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
resources = stack.describe_resources()
|
||||
instance_profile_resource = [resource for resource in resources if resource.resource_type == 'AWS::IAM::InstanceProfile'][0]
|
||||
instance_profile_resource.physical_resource_id.should.equal(instance_profile.instance_profile_name)
|
||||
|
||||
role_resource = [resource for resource in resources if resource.resource_type == 'AWS::IAM::Role'][0]
|
||||
role_resource.physical_resource_id.should.equal(role.role_id)
|
||||
|
||||
|
||||
@mock_ec2()
|
||||
@mock_cloudformation()
|
||||
def test_single_instance_with_ebs_volume():
|
||||
|
||||
template_json = json.dumps(single_instance_with_ebs_volume.template)
|
||||
conn = boto.connect_cloudformation()
|
||||
conn.create_stack(
|
||||
"test_stack",
|
||||
template_body=template_json,
|
||||
)
|
||||
|
||||
ec2_conn = boto.connect_ec2()
|
||||
reservation = ec2_conn.get_all_instances()[0]
|
||||
ec2_instance = reservation.instances[0]
|
||||
|
||||
volume = ec2_conn.get_all_volumes()[0]
|
||||
volume.volume_state().should.equal('in-use')
|
||||
volume.attach_data.instance_id.should.equal(ec2_instance.id)
|
||||
|
||||
stack = conn.describe_stacks()[0]
|
||||
resources = stack.describe_resources()
|
||||
ebs_volume = [resource for resource in resources if resource.resource_type == 'AWS::EC2::Volume'][0]
|
||||
ebs_volume.physical_resource_id.should.equal(volume.id)
|
||||
0
tests/test_cloudformation/test_server.py
Normal file
0
tests/test_cloudformation/test_server.py
Normal file
47
tests/test_cloudformation/test_stack_parsing.py
Normal file
47
tests/test_cloudformation/test_stack_parsing.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import json
|
||||
|
||||
from mock import patch
|
||||
import sure # noqa
|
||||
|
||||
from moto.cloudformation.models import FakeStack
|
||||
from moto.cloudformation.parsing import resource_class_from_type
|
||||
from moto.sqs.models import Queue
|
||||
|
||||
dummy_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
|
||||
"Description": "Create a multi-az, load balanced, Auto Scaled sample web site. The Auto Scaling trigger is based on the CPU utilization of the web servers. The AMI is chosen based on the region in which the stack is run. This example creates a web service running across all availability zones in a region. The instances are load balanced with a simple health check. The web site is available on port 80, however, the instances can be configured to listen on any port (8888 by default). **WARNING** This template creates one or more Amazon EC2 instances. You will be billed for the AWS resources used if you create a stack from this template.",
|
||||
|
||||
"Resources": {
|
||||
"WebServerGroup": {
|
||||
|
||||
"Type": "AWS::SQS::Queue",
|
||||
"Properties": {
|
||||
"QueueName": "my-queue",
|
||||
"VisibilityTimeout": 60,
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
dummy_template_json = json.dumps(dummy_template)
|
||||
|
||||
|
||||
def test_parse_stack_resources():
|
||||
stack = FakeStack(
|
||||
stack_id="test_id",
|
||||
name="test_stack",
|
||||
template=dummy_template_json,
|
||||
)
|
||||
|
||||
stack.resource_map.should.have.length_of(1)
|
||||
stack.resource_map.keys()[0].should.equal('WebServerGroup')
|
||||
queue = stack.resource_map.values()[0]
|
||||
queue.should.be.a(Queue)
|
||||
queue.name.should.equal("my-queue")
|
||||
|
||||
|
||||
@patch("moto.cloudformation.parsing.logger")
|
||||
def test_missing_resource_logs(logger):
|
||||
resource_class_from_type("foobar")
|
||||
logger.warning.assert_called_with('No Moto CloudFormation support for %s', 'foobar')
|
||||
27
tests/test_iam/test_iam.py
Normal file
27
tests/test_iam/test_iam.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import boto
|
||||
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_iam
|
||||
|
||||
|
||||
@mock_iam()
|
||||
def test_create_role_and_instance_profile():
|
||||
conn = boto.connect_iam()
|
||||
conn.create_instance_profile("my-profile", path="my-path")
|
||||
conn.create_role("my-role", assume_role_policy_document="some policy", path="my-path")
|
||||
|
||||
conn.add_role_to_instance_profile("my-profile", "my-role")
|
||||
|
||||
role = conn.get_role("my-role")
|
||||
role.path.should.equal("my-path")
|
||||
role.assume_role_policy_document.should.equal("some policy")
|
||||
|
||||
profile = conn.get_instance_profile("my-profile")
|
||||
profile.path.should.equal("my-path")
|
||||
role_from_profile = profile.roles.values()[0]
|
||||
role_from_profile['role_id'].should.equal(role.role_id)
|
||||
role_from_profile['role_name'].should.equal("my-role")
|
||||
|
||||
conn.list_roles().roles[0].role_name.should.equal('my-role')
|
||||
conn.list_instance_profiles().instance_profiles[0].instance_profile_name.should.equal("my-profile")
|
||||
Loading…
Add table
Add a link
Reference in a new issue