def _get_resources(self): resources = [ Resource( "CoreOSSecurityGroup", "AWS::EC2::SecurityGroup", Properties({ "VpcId": { "Ref": "VPC" }, "GroupDescription": "CoreOS SecurityGroup", "SecurityGroupIngress": [{ "CidrIp": "10.0.0.0/16", "IpProtocol": "udp", "FromPort": "0", "ToPort": "65535" }, { "CidrIp": "10.0.0.0/16", "IpProtocol": "icmp", "FromPort": "-1", "ToPort": "-1" }], "Tags": [{ "Key": "Name", "Value": "CoreOSSecurityGroup" }] })), Resource( "CoreOSSecurityGroup2380Ingress", "AWS::EC2::SecurityGroupIngress", Properties({ "GroupId": { "Ref": "CoreOSSecurityGroup" }, "IpProtocol": "tcp", "FromPort": "2380", "ToPort": "2380", # "SourceSecurityGroupId": {"Ref": "CoreOSSecurityGroup"} # TODO not working for now because need to use fleetctl locally to load units "CidrIp": "10.0.0.0/16" }), attributes=[DependsOn("CoreOSSecurityGroup")]), Resource( "CoreOSSecurityGroup2379Ingress", "AWS::EC2::SecurityGroupIngress", Properties({ "GroupId": { "Ref": "CoreOSSecurityGroup" }, "IpProtocol": "tcp", "FromPort": "2379", "ToPort": "2379", # "SourceSecurityGroupId": {"Ref": "CoreOSSecurityGroup"} # TODO not working for now because need to use fleetctl locally to load units "CidrIp": "10.0.0.0/16" }), attributes=[DependsOn("CoreOSSecurityGroup")]) ] resources += self._get_etcd_cluster_resources() resources += self._get_coreos_resources() return resources
def _get_resources(self): resources = [] dns_suffix = self.data['dns_suffix'] for prefix in self.DNS_MAPPING: name = self._get_dns_record_name(prefix) if prefix != '': prefix = "%s." % prefix resources.append( Resource( name, "AWS::Route53::RecordSet", Properties({ "HostedZoneName": dns_suffix, "Comment": "DNS name for TeamCity", "Name": { "Fn::Join": [ "", [prefix, { "Ref": "EnvName" }, '.', dns_suffix] ] }, "Type": "CNAME", "TTL": "60", "ResourceRecords": [{ "Fn::GetAtt": ["PublicELB", "CanonicalHostedZoneName"] }] }))) return resources
def _get_resources(self): resources = [ Resource( "VPC", "AWS::EC2::VPC", Properties({ "CidrBlock": { "Fn::FindInMap": ["SubnetConfig", "VPC", "CIDR"] }, "EnableDnsSupport": "true", "EnableDnsHostnames": "true", "Tags": [{ "Key": "Application", "Value": { "Ref": "AWS::StackId" } }] })), Resource( "InternetGateway", "AWS::EC2::InternetGateway", Properties({ "Tags": [{ "Key": "Application", "Value": { "Ref": "AWS::StackId" } }] })), Resource( "GatewayToInternet", "AWS::EC2::VPCGatewayAttachment", Properties({ "VpcId": { "Ref": "VPC" }, "InternetGatewayId": { "Ref": "InternetGateway" } })) ] resources += self._get_public_subnets() resources += self._get_private_subnets() return resources
from cfn_pyplates.core import CloudFormationTemplate, Resource from cfn_pyplates.core import Properties, options from utils import nametag cft = CloudFormationTemplate(description="Tooltool Infrastructure") rgn = options['region'] # production cft.resources.add(Resource( 'FileBucket', 'AWS::S3::Bucket', Properties({ "AccessControl": "Private", "BucketName": "mozilla-releng-%s-tooltool" % (rgn,), 'Tags': [nametag('Tooltool File Storage - %s' % (rgn,))], }) )) # staging cft.resources.add(Resource( 'StagingFileBucket', 'AWS::S3::Bucket', Properties({ "AccessControl": "Private", "BucketName": "mozilla-releng-staging-%s-tooltool" % (rgn,), 'Tags': [nametag('Tooltool File Storage - Staging - %s' % (rgn,))], }) ))
def make_storage_template(): cft = CloudFormationTemplate(description="Refinery Platform storage") # Parameters cft.parameters.add( Parameter('StaticBucketName', 'String', { 'Description': 'Name of S3 bucket for Django static files', })) cft.parameters.add( Parameter( 'MediaBucketName', 'String', { 'Description': 'Name of S3 bucket for Django media files', # make names DNS-compliant without periods (".") for compatibility # with virtual-hosted-style access and S3 Transfer Acceleration 'AllowedPattern': '[a-z0-9\-]+', 'ConstraintDescription': 'must only contain lower case letters, numbers, and hyphens', })) # Resources cft.resources.add( Resource( 'StaticStorageBucket', 'AWS::S3::Bucket', Properties({ 'BucketName': ref('StaticBucketName'), 'AccessControl': 'PublicRead', 'CorsConfiguration': { 'CorsRules': [{ 'AllowedOrigins': ['*'], 'AllowedMethods': ['GET'], 'AllowedHeaders': ['Authorization'], 'MaxAge': 3000, }] }, }), DeletionPolicy('Retain'), )) cft.resources.add( Resource( 'MediaStorageBucket', 'AWS::S3::Bucket', Properties({ 'BucketName': ref('MediaBucketName'), 'AccessControl': 'PublicRead', 'CorsConfiguration': { 'CorsRules': [{ 'AllowedOrigins': ['*'], 'AllowedMethods': ['POST', 'PUT', 'DELETE'], 'AllowedHeaders': ['*'], 'ExposedHeaders': ['ETag'], 'MaxAge': 3000, }] } }), DeletionPolicy('Retain'), )) cft.outputs.add( Output('MediaBucketName', ref('MediaStorageBucket'), {'Fn::Sub': '${AWS::StackName}Media'}, 'Name of S3 bucket for Django media files')) return cft
Properties({ 'Policies': [ policy("tooltoolbucketaccess", { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:ListBucketMultipartUploads", "s3:ListBucketVersions", ], "Resource": [ bucket_arn('use1'), bucket_arn('usw1'), bucket_arn('usw2') ] }), policy("tooltoolobjectaccess", { "Effect": "Allow", "Action": [ "s3:AbortMultipartUpload", "s3:DeleteObject", "s3:DeleteObjectVersion", "s3:GetObject", "s3:GetObjectAcl", "s3:GetObjectTorrent", "s3:GetObjectVersion", "s3:GetObjectVersionAcl", "s3:GetObjectVersionTorrent", "s3:ListMultipartUploadParts", "s3:PutObject", "s3:PutObjectAcl", "s3:PutObjectVersionAcl", "s3:RestoreObject" ], "Resource": [ object_arn('use1'), object_arn('usw1'), object_arn('usw2') ] }), ] })
def _get_resources(self): return [ Resource( "PublicELB", "AWS::ElasticLoadBalancing::LoadBalancer", Properties({ "Subnets": [{ "Ref": subnet_name } for subnet_name in self.data['public_subnets']], "SecurityGroups": [{ "Ref": "PublicHTTPSecurityGroup" }], "Listeners": [{ "LoadBalancerPort": "80", "InstancePort": "8080", "Protocol": "HTTP" }], "HealthCheck": { "Target": "HTTP:8080/", "HealthyThreshold": "3", "UnhealthyThreshold": "5", "Interval": "30", "Timeout": "5" } })), Resource( "PublicELBIAMUser", "AWS::IAM::User", Properties({ "Policies": [{ "PolicyName": "PublicELBRegisterDeregisterOnly", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", "elasticloadbalancing:RegisterInstancesWithLoadBalancer" ], "Resource": { "Fn::Join": [ "", [ "arn:aws:elasticloadbalancing:", { "Ref": "AWS::Region" }, ":", { "Ref": "AWS::AccountId" }, ":loadbalancer/", { "Ref": "PublicELB" } ] ] } }] } }] })), Resource("PublicELBAccessKey", "AWS::IAM::AccessKey", Properties({"UserName": { "Ref": "PublicELBIAMUser" }})) ]
def _get_resources(self): return [ Resource( "MasterDBSubnetGroup", "AWS::RDS::DBSubnetGroup", Properties({ "DBSubnetGroupDescription": "Master DB subnet group", "SubnetIds": [{ "Ref": subnet_name } for subnet_name in self.data['private_subnets']] })), Resource( "MasterDBSecurityGroup", "AWS::EC2::SecurityGroup", Properties({ "VpcId": { "Ref": "VPC" }, "GroupDescription": "Ingress for CoreOS instance security group", "SecurityGroupIngress": [{ "SourceSecurityGroupId": { "Ref": "CoreOSSecurityGroup" }, "IpProtocol": "tcp", "FromPort": "5432", "ToPort": "5432" }], "Tags": [{ "Key": "Name", "Value": "MasterDBSecurityGroup" }] })), Resource( "PrimaryDB", "AWS::RDS::DBInstance", Properties({ "DBName": { "Ref": "DBName" }, "AllocatedStorage": { "Ref": "DBAllocatedStorage" }, "DBInstanceClass": { "Ref": "DBInstanceClass" }, "Engine": "postgres", "EngineVersion": "9.3.5", "MasterUsername": { "Ref": "DBUsername" }, "MasterUserPassword": { "Ref": "DBPassword" }, "Port": "5432", "VPCSecurityGroups": [{ "Ref": "MasterDBSecurityGroup" }], "PubliclyAccessible": "false", "PreferredMaintenanceWindow": "sun:12:00-sun:12:30", "PreferredBackupWindow": "23:00-23:30", "BackupRetentionPeriod": "7", "DBParameterGroupName": "default.postgres9.3", "AutoMinorVersionUpgrade": "true", "MultiAZ": "false", "DBSubnetGroupName": { "Ref": "MasterDBSubnetGroup" }, "Tags": [{ "Key": "Role", "Value": "Primary" }] })) ]
from cfn_pyplates.core import Properties, options from utils import nametag from utils import sgcidr cft = CloudFormationTemplate(description="IT Resources") cft.resources.add(Resource( 'NagiosSG', 'AWS::EC2::SecurityGroup', Properties({ 'GroupDescription': 'Nagios Servers', 'Tags': [nametag('nagios')], 'VpcId': options['vpcid'], 'SecurityGroupIngress': [ sgcidr('10.22.8.128/32', -1, -1), sgcidr('10.22.20.0/25', -1, -1), sgcidr('10.22.72.136/32', -1, -1), sgcidr('10.22.72.155/32', -1, -1), sgcidr('10.22.72.158/32', -1, -1), sgcidr('10.22.72.159/32', -1, -1), sgcidr('10.22.75.5/32', -1, -1), sgcidr('10.22.75.6/31', -1, -1), sgcidr('10.22.240.0/20', -1, -1), sgcidr('10.22.74.22/32', -1, -1), sgcidr('10.22.75.30/32', -1, -1), sgcidr('10.22.75.36/32', 'tcp', 22), sgcidr('10.22.75.136/32', 'udp', 161), sgcidr('0.0.0.0/0', 'icmp', -1), ], }), ))
def _get_coreos_resources(self): resources = self._get_autoscale( 'CoreOS', extra_security_groups=[ 'CoreOSSecurityGroup', 'WebAppSecurityGroup' ], extra_cloud_config=[ "coreos:\n", " etcd2:\n", " discovery: ", { "Ref": "DiscoveryURL" }, "\n", " proxy: on\n", " listen-client-urls: http://0.0.0.0:2379\n" " fleet:\n", " metadata: \"role=worker\"\n", " etcd_servers: http://127.0.0.1:2379\n", " flannel:\n", " etcd_endpoints: http://127.0.0.1:2379\n", " units:\n", " - name: etcd2.service\n", " command: start\n", " - name: fleet.service\n", " command: start\n", " - name: flanneld.service\n", " drop-ins:\n", " - name: 50-network-config.conf\n", " content: |\n", " [Unit]\n", " Requires=etcd2.service\n", " [Service]\n", " ExecStartPre=/usr/bin/etcdctl set /coreos.com/network/config '{ \"Network\": \"192.168.192.0/18\", \"Backend\": {\"Type\": \"vxlan\"}}'\n", " command: start\n" ], config_min_size=1, config_max_size=12, extra_props_autoscale={ "VPCZoneIdentifier": [{ "Ref": subnet_name } for subnet_name in self.data['private_subnets']], "DesiredCapacity": { "Ref": "CoreOSClusterSize" } }) resources.append( Resource( "WebAppSecurityGroup", "AWS::EC2::SecurityGroup", Properties({ "VpcId": { "Ref": "VPC" }, "GroupDescription": "WebApp SecurityGroup", "SecurityGroupIngress": [{ "IpProtocol": "tcp", "FromPort": "8080", "ToPort": "8080", "SourceSecurityGroupId": { "Ref": "NATSecurityGroup" } }, { "IpProtocol": "tcp", "FromPort": "8080", "ToPort": "8080", "SourceSecurityGroupId": { "Ref": "PublicHTTPSecurityGroup" } }], "Tags": [{ "Key": "Name", "Value": "WebAppSecurityGroup" }] }))) return resources
def _get_resources(self): return [ Resource( "NATSecurityGroup", "AWS::EC2::SecurityGroup", Properties({ "VpcId": { "Ref": "VPC" }, "GroupDescription": "NAT Instance Security Group", "SecurityGroupIngress": [{ "IpProtocol": "icmp", "FromPort": "-1", "ToPort": "-1", "CidrIp": "10.0.0.0/16" }, { "IpProtocol": "tcp", "FromPort": "0", "ToPort": "65535", "CidrIp": "10.0.0.0/16" }], "Tags": [{ "Key": "Name", "Value": "NATSecurityGroup" }] })), Resource("NATInstance", "AWS::EC2::Instance", Properties({ "ImageId": { "Fn::FindInMap": ["RegionMap", { "Ref": "AWS::Region" }, "nat"] }, "InstanceType": { "Ref": "NATInstanceType" }, "BlockDeviceMappings": [{ "DeviceName": "/dev/xvda", "Ebs": { "VolumeSize": 10 } }], "NetworkInterfaces": [{ "GroupSet": [{ "Ref": "NATSecurityGroup" }, { "Ref": "SSHFromBastionSecurityGroup" }], "SubnetId": { "Ref": self.data['public_subnets'][0] }, "AssociatePublicIpAddress": "true", "DeviceIndex": "0", "DeleteOnTermination": "true" }], "SourceDestCheck": "false", "Tags": [{ "Key": "Name", "Value": "NATHost" }, { "Key": "Role", "Value": "NAT" }], "UserData": { "Fn::Base64": { "Fn::Join": ["", self.get_user_cloud_config()] } } }), attributes=[DependsOn("GatewayToInternet")]) ]
def _get_private_subnets(self): resources = [ Resource( "PrivateRouteTable", "AWS::EC2::RouteTable", Properties({ "VpcId": { "Ref": "VPC" }, "Tags": [{ "Key": "Name", "Value": "PrivateRouteTable" }] })), Resource("PrivateInternetRoute", "AWS::EC2::Route", Properties({ "RouteTableId": { "Ref": "PrivateRouteTable" }, "DestinationCidrBlock": "0.0.0.0/0", "InstanceId": { "Ref": "NATInstance" } }), attributes=[DependsOn("NATInstance")]), ] for subnet_name in self.data['private_subnets']: table_association_name = "%sRouteTableAssociation" % subnet_name resources += [ Resource( subnet_name, "AWS::EC2::Subnet", Properties({ "VpcId": { "Ref": "VPC" }, "AvailabilityZone": { "Fn::FindInMap": ["SubnetConfig", subnet_name, "AZ"] }, "CidrBlock": { "Fn::FindInMap": ["SubnetConfig", subnet_name, "CIDR"] }, "Tags": [{ "Key": "Application", "Value": { "Ref": "AWS::StackId" } }, { "Key": "Network", "Value": subnet_name }] })), Resource( table_association_name, "AWS::EC2::SubnetRouteTableAssociation", Properties({ "SubnetId": { "Ref": subnet_name }, "RouteTableId": { "Ref": "PrivateRouteTable" } })), ] return resources
def _get_autoscale(self, name, extra_security_groups=[], extra_cloud_config='', extra_props_autoscale={}, extra_props_launch={}, extra_attrs_launch=[], config_min_size=3, config_max_size=3): # general configs autoscale_name = '%sServerAutoScale' % name autoscale_launch_config = '%sServerLaunchConfig' % name # autoscaling configs props_autoscale = { "AvailabilityZones": { "Fn::GetAZs": { "Ref": "AWS::Region" } }, "LaunchConfigurationName": { "Ref": autoscale_launch_config }, "MinSize": "%s" % config_min_size, "MaxSize": "%s" % config_max_size, "Tags": [{ "Key": "Name", "Value": name, "PropagateAtLaunch": True }, { "Key": "Role", "Value": name, "PropagateAtLaunch": True }] } props_autoscale.update(extra_props_autoscale) # launch configs sec_groups = [{ "Ref": sec_group } for sec_group in ["SSHFromBastionSecurityGroup"] + extra_security_groups] cloud_config = self.get_user_cloud_config() cloud_config += extra_cloud_config props_launch = { "ImageId": { "Fn::FindInMap": ["RegionMap", { "Ref": "AWS::Region" }, name] }, "InstanceType": { "Ref": "%sInstanceType" % name }, "SecurityGroups": sec_groups, "UserData": { "Fn::Base64": join('', *cloud_config) } } props_launch.update(extra_props_launch) attrs_launch = extra_attrs_launch return [ Resource(autoscale_name, "AWS::AutoScaling::AutoScalingGroup", Properties(props_autoscale)), Resource(autoscale_launch_config, "AWS::AutoScaling::LaunchConfiguration", Properties(props_launch), attributes=attrs_launch) ]
def _get_resources(self): return [ Resource( "PublicHTTPSecurityGroup", "AWS::EC2::SecurityGroup", Properties({ "VpcId": { "Ref": "VPC" }, "GroupDescription": "Ingress for port 80 from anywhere", "SecurityGroupIngress": [{ "CidrIp": "0.0.0.0/0", "IpProtocol": "tcp", "FromPort": "80", "ToPort": "80" }], "Tags": [{ "Key": "Name", "Value": "PublicHTTPSecurityGroup" }] })), Resource( "SSHBastionSecurityGroup", "AWS::EC2::SecurityGroup", Properties({ "VpcId": { "Ref": "VPC" }, "GroupDescription": "Ingress for SSH from anywhere", "SecurityGroupIngress": [{ "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "CidrIp": "0.0.0.0/0" }], "Tags": [{ "Key": "Name", "Value": "SSHBastionSecurityGroup" }] })), Resource( "SSHFromBastionSecurityGroup", "AWS::EC2::SecurityGroup", Properties({ "VpcId": { "Ref": "VPC" }, "GroupDescription": "SSH from SSH Bastion SecurityGroup", "SecurityGroupIngress": [{ "IpProtocol": "tcp", "FromPort": "22", "ToPort": "22", "SourceSecurityGroupId": { "Ref": "SSHBastionSecurityGroup" } }], "Tags": [{ "Key": "Name", "Value": "SSHFromBastionSecurityGroup" }] })), Resource( "SQSUser", "AWS::IAM::User", Properties({ "Policies": [{ "PolicyName": "AmazonSQSFullAccess", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["sqs:*"], "Resource": "*" }] } }] })), Resource("SQSAccessKey", "AWS::IAM::AccessKey", Properties({"UserName": { "Ref": "SQSUser" }})) ]
def make_storage_template(): cft = CloudFormationTemplate(description="Refinery Platform storage") # Parameters cft.parameters.add( Parameter('StaticBucketName', 'String', { 'Description': 'Name of S3 bucket for Django static files', })) cft.parameters.add( Parameter( 'MediaBucketName', 'String', { 'Description': 'Name of S3 bucket for Django media files', # make names DNS-compliant without periods (".") for # compatibility with virtual-hosted-style access and S3 # Transfer Acceleration 'AllowedPattern': '[a-z0-9\-]+', 'ConstraintDescription': 'must only contain lower case letters, numbers, and ' 'hyphens', })) cft.parameters.add( Parameter( 'IdentityPoolName', 'String', { 'Default': 'Refinery Platform', 'Description': 'Name of Cognito identity pool for S3 uploads', })) cft.parameters.add( Parameter( 'DeveloperProviderName', 'String', { 'Default': 'login.refinery', 'Description': '"domain" by which Cognito will refer to users', 'AllowedPattern': '[a-z\-\.]+', 'ConstraintDescription': 'must only contain lower case letters, periods, ' 'underscores, and hyphens' })) # Resources cft.resources.add( Resource( 'StaticStorageBucket', 'AWS::S3::Bucket', Properties({ 'BucketName': ref('StaticBucketName'), 'AccessControl': 'PublicRead', 'CorsConfiguration': { 'CorsRules': [{ 'AllowedOrigins': ['*'], 'AllowedMethods': ['GET'], 'AllowedHeaders': ['Authorization'], 'MaxAge': 3000, }] }, }), DeletionPolicy('Retain'), )) cft.resources.add( Resource( 'MediaStorageBucket', 'AWS::S3::Bucket', Properties({ 'BucketName': ref('MediaBucketName'), 'AccessControl': 'PublicRead', 'CorsConfiguration': { 'CorsRules': [{ 'AllowedOrigins': ['*'], 'AllowedMethods': ['POST', 'PUT', 'DELETE'], 'AllowedHeaders': ['*'], 'ExposedHeaders': ['ETag'], 'MaxAge': 3000, }] } }), DeletionPolicy('Retain'), )) # Cognito Identity Pool for Developer Authenticated Identities Authflow # http://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow.html cft.resources.add( Resource( 'IdentityPool', 'AWS::Cognito::IdentityPool', Properties({ 'IdentityPoolName': ref('IdentityPoolName'), 'AllowUnauthenticatedIdentities': False, 'DeveloperProviderName': ref('DeveloperProviderName'), }))) cft.resources.add( Resource( 'IdentityPoolAuthenticatedRole', 'AWS::Cognito::IdentityPoolRoleAttachment', Properties({ 'IdentityPoolId': ref('IdentityPool'), 'Roles': { 'authenticated': get_att('CognitoS3UploadRole', 'Arn'), } }))) upload_role_trust_policy = { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Federated": "cognito-identity.amazonaws.com" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "cognito-identity.amazonaws.com:aud": ref('IdentityPool') }, "ForAnyValue:StringLike": { "cognito-identity.amazonaws.com:amr": "authenticated" } } }] } upload_access_policy = { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["cognito-identity:*"], "Resource": "*" }, { "Action": ["s3:PutObject", "s3:AbortMultipartUpload"], "Effect": "Allow", "Resource": { "Fn::Sub": "arn:aws:s3:::${MediaStorageBucket}/uploads/" "${!cognito-identity.amazonaws.com:sub}/*" } }] } cft.resources.add( Resource( 'CognitoS3UploadRole', 'AWS::IAM::Role', Properties({ 'AssumeRolePolicyDocument': upload_role_trust_policy, 'Policies': [{ 'PolicyName': 'AuthenticatedS3UploadPolicy', 'PolicyDocument': upload_access_policy, }] }))) # Outputs cft.outputs.add( Output('IdentityPoolId', ref('IdentityPool'), {'Fn::Sub': '${AWS::StackName}IdentityPoolId'}, 'Cognito identity pool ID')) return cft
def resolve_host(hostname): ips = dns.resolver.query(hostname, "A") # sort these so that we deterministically set up the same route # resources (until DNS changes) ips = sorted([i.to_text() for i in ips]) return ips # VPC cft = CloudFormationTemplate(description="Release Engineering network configuration") cft.resources.add(Resource( 'RelengVPC', 'AWS::EC2::VPC', Properties({ 'CidrBlock': subnet_cidr('0.0', 16), 'Tags': [nametag('Releng Network')], }) )) # DHCP options cft.resources.add(Resource( 'DHCPOptions', 'AWS::EC2::DHCPOptions', Properties({ # point to the onsite, IT-managed DNS servers 'DomainNameServers': [ "10.26.75.40", "10.26.75.41" ], 'Tags': [nametag('Releng Network Options')], })
from cfn_pyplates.core import CloudFormationTemplate, Resource from cfn_pyplates.core import Properties, options from utils import nametag cft = CloudFormationTemplate(description="Archiver Infrastructure") rgn = options['region'] # production cft.resources.add(Resource( 'FileBucket', 'AWS::S3::Bucket', Properties({ "AccessControl": "Private", "BucketName": "mozilla-releng-%s-archiver" % (rgn,), 'Tags': [nametag('Archiver Archive Storage - %s' % (rgn,))], }) )) # staging cft.resources.add(Resource( 'StagingFileBucket', 'AWS::S3::Bucket', Properties({ "AccessControl": "Private", "BucketName": "mozilla-releng-staging-%s-archiver" % (rgn,), 'Tags': [nametag('Archiver Archive Storage - Staging - %s' % (rgn,))], }) ))