def __init__(self, leaf_title, template, dependencies, public_cidr, public_hosted_zone_name, cd_service_role_arn, availability_zones, tree_name, elb_config, asg_config, keypair): """ Create autoscaling resources within a cross referenced stack :param leaf_title: title of the amazonia leaf and associated resources to be used in cloud formation :param public_cidr: public cidr pattern, this can either allow public access or restrict to an organisation :param public_hosted_zone_name: the hosted zone name to create R53 records in :param cd_service_role_arn: ARN of the code deploy service role :param availability_zones: List of availability zones autoscaling resources can use :param tree_name: name of cross referenced stack :param keypair: keypair to use with autoscaling instances :param template: Troposphere template to append resources to :param dependencies: list of unit names this unit needs access to :param elb_config: config related to Elastic Load Balancer :param asg_config: config related to AutoScaling Group """ self.set_tree_config(template=template, availability_zones=availability_zones, tree_name=tree_name) self.tree_config.public_hosted_zone_name = public_hosted_zone_name self.tree_config.cd_service_role_arn = cd_service_role_arn self.tree_config.availability_zones = availability_zones self.tree_config.keypair = keypair self.tree_config.public_cidr = public_cidr self.tree_config.private_hosted_zone_id = ImportValue( self.tree_name + '-PrivateHostedZoneId') self.tree_config.private_hosted_zone_domain = ImportValue( self.tree_name + '-PrivateHostedZoneDomain') super(AutoscalingLeaf, self).__init__(leaf_title, template, self.tree_config, elb_config, asg_config, dependencies, asg_config.ec2_scheduled_shutdown) self.template.add_output( Output('elbSecurityGroup', Description='ELB Security group', Value=self.elb.security_group, Export=Export(tree_name + '-' + leaf_title + '-SecurityGroup'))) self.template.add_output( Output('elbEndpoint', Description='Endpoint of the {0} ELB'.format(self.title), Value=GetAtt(self.elb.trop_elb, 'DNSName'), Export=Export(tree_name + '-' + leaf_title + '-Endpoint'))) for dependency in self.dependencies: portless_dependency_name = dependency.split(':')[0] dependency_port = dependency.split(':')[1] target_leaf_sg = RemoteReferenceSecurityEnabledObject( template=template, reference_title=self.tree_name + '-' + portless_dependency_name + '-SecurityGroup') self.asg.add_flow(receiver=target_leaf_sg, port=dependency_port)
def generate(template): artifact_bucket = template.add_parameter( Parameter('AuthorizerArtifactBucket', Type='String')) artifact_name = template.add_parameter( Parameter('AuthorizerArtifactName', Type='String')) artifact_version = template.add_parameter( Parameter('AuthorizerArtifactVersion', Type='String')) fnrole = template.add_resource( iam.Role( 'DeviceAuthorizerFnRole', RoleName='DeviceAuthorizerFnRole', ManagedPolicyArns=[ "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", ], AssumeRolePolicyDocument=awacs.aws.PolicyDocument( Version='2012-10-17', Statement=[ awacs.aws.Statement( Effect=awacs.aws.Allow, Action=[awacs.sts.AssumeRole], Principal=awacs.aws.Principal("Service", "lambda.amazonaws.com"), ) ]))) lambdafn = template.add_resource( awslambda.Function('DeviceAuthorizerFn', FunctionName='DeviceAuthorizerFn', Runtime='nodejs10.x', MemorySize=128, Timeout=10, Handler='index.handler', Role=GetAtt(fnrole, "Arn"), Code=awslambda.Code( S3Bucket=Ref(artifact_bucket), S3Key=Ref(artifact_name), S3ObjectVersion=Ref(artifact_version), ))) template.add_output( Output('DeviceAuthorizerFn', Export=Export('DeviceAuthorizerFn'), Value=Ref(lambdafn))) template.add_output( Output('DeviceAuthorizerFnArn', Export=Export('DeviceAuthorizerFnArn'), Value=GetAtt(lambdafn, "Arn"))) return lambdafn
def create_elbv2(self, name, subnets, security_groups=[], lb_type="application", scheme="internet-facing", tags={}, lb_attributes=False): """ Creates an Amazon Load Balancer (ELBv2) - (software load balancer) not to be confused with an ELB :param name: Name for the ALB :param subnets: Subnets in which to create it (must be >1) :param security_groups: SGs to assign to the ALB :param lb_type: LB type (application, network) :param scheme: Scheme (internet-facing, internal) :param tags: any tags to assign to the LB :param lb_attributes: Additional attributes """ load_balancer = elbv2.LoadBalancer(name, Subnets=subnets, SecurityGroups=security_groups, Scheme=scheme, Type=lb_type, Tags=tags) if lb_attributes: attributes = [] for attr in lb_attributes: attributes.append( elbv2.LoadBalancerAttributes(Key=attr['key'], Value=attr['value'])) load_balancer.LoadBalancerAttributes = attributes self.template.add_resource(load_balancer) if lb_type == "application": lb_abbreviation = "ALB" elif lb_type == "network": lb_abbreviation = "NLB" self.template.add_output( Output( # Todo Sort out outputs, based on Type. name, Value=Ref(name), Description=lb_abbreviation + u" ARN", Export=Export(Sub("${AWS::StackName}-" + name)))) self.template.add_output( Output(name + "DNS", Value=GetAtt(name, "DNSName"), Description=lb_abbreviation + u" DNS Name.", Export=Export(Sub("${AWS::StackName}-" + name + "DNS"))))
def object_outputs(template_resource, supports_arn=False, export=False, append_title=False, name_is_id=False): """ Args: template_object: Troposphere resource object to extract outputs from export: bool: Exports the value to the Region for other stacks to use suports_arn: bool: If the object supports GetAtt(object, 'Arn'), set to true to add the ARN to the outputs kwargs: key-pair values to add more tags Returns: outputs: list: list of Output() object for the Troposphere template """ outputs = [] object_type = get_resource_type(template_resource) name_ext = 'Name' if name_is_id: name_ext = 'Id' suffix = name_ext export_name = f'${{AWS::StackName}}-{object_type}' if append_title: export_name = f'${{AWS::StackName}}-{object_type}-{template_resource.title}' output = Output(f'{template_resource.title}{name_ext}', Value=Ref(template_resource)) if export: setattr(output, 'Export', Export(Sub(f'{export_name}-{suffix}'))) outputs.append(output) if supports_arn: output = Output(f'{template_resource.title}Arn', Value=GetAtt(template_resource, 'Arn')) if export: setattr(output, 'Export', Export(Sub(f'{export_name}-Arn'))) outputs.append(output) if isinstance(template_resource, Role): output = Output(f'{template_resource.title}UniqueId', Value=GetAtt(template_resource, 'RoleId')) if export: setattr(output, 'Export', Export(Sub(f'{export_name}-RoleId'))) outputs.append(output) elif isinstance(template_resource, LayerVersion): output = Output(f'{template_resource.title}Arn', Value=Ref(template_resource)) if export: setattr(output, 'Export', Export(Sub(f'{export_name}-Arn'))) outputs.append(output) return outputs
def dump_lab_yaml(cfn_file): template = Template() key_name_param = template.add_parameter( Parameter( "keyName", Description="string of vpc cidr block to use", Type="String", )) ami_id_param = template.add_parameter( Parameter("AmiId", Description="string of vpc cidr block to use", Type="AWS::EC2::Image::Id")) instance_type_param = template.add_parameter( Parameter( "InstanceType", Description="string of vpc cidr block to use", Type="String", )) instance = template.add_resource( ec2.Instance( "MyInstance", ImageId=Ref(ami_id_param), SubnetId=ImportValue("SubnetId-jdix"), InstanceType=Ref(instance_type_param), KeyName=Ref(key_name_param), Tags=resource_tags, )) template.add_output([ Output( "InstanceId", Description="InstanceId of the newly created EC2 instance", Value=Ref(instance), Export=Export("InstanceId-jdix"), ), Output( "InstancePrivateIP", Description="InstanceId of the newly created EC2 instance", Value=GetAtt(instance, "PrivateIp"), Export=Export("InstancePrivateIP-jdix"), ) ]) template_out_yaml(cfn_file, template)
def add_resources(self): """Add resources to template.""" template = self.template variables = self.get_variables() targetgroup = template.add_resource( elasticloadbalancingv2.TargetGroup( 'TargetGroup', HealthCheckIntervalSeconds=variables[ 'HealthCheckIntervalSeconds'].ref, HealthCheckPath=variables['HealthCheckPath'].ref, HealthCheckPort=variables['HealthCheckPort'].ref, HealthCheckProtocol=variables['HealthCheckProtocol'].ref, HealthCheckTimeoutSeconds=variables[ 'HealthCheckTimeoutSeconds'].ref, HealthyThresholdCount=variables['HealthyThresholdCount'].ref, UnhealthyThresholdCount=variables['UnhealthyThresholdCount']. ref, Matcher=elasticloadbalancingv2.Matcher( HttpCode=variables['HealthCheckSuccessCodes'].ref), Name=variables['TargetGroupName'].ref, Port=variables['AppPort'].ref, Protocol=variables['AppProtocol'].ref, Tags=Tags(Application=variables['ApplicationName'].ref, Environment=variables['EnvironmentName'].ref), TargetType=variables['TargetType'].ref, VpcId=variables['VpcId'].ref)) template.add_output( Output("{}Arn".format(targetgroup.title), Description="ARN of the Target Group", Value=Ref(targetgroup), Export=Export( Sub('${AWS::StackName}-%sArn' % targetgroup.title))))
def add_resource_and_output(self): """Add resources to template.""" template = self.template variables = self.get_variables() networkinterfaces = [] for di, netintid in variables['NetworkInterfaces'].iteritems(): networkinterfaces.append( ec2.NetworkInterfaceProperty(DeviceIndex=di, NetworkInterfaceId=netintid)) ec2instance = template.add_resource( ec2.Instance( 'PaEc2Instance', DisableApiTermination='true', # s4f # IamInstanceProfile=variables['InstanceProfile'].ref, ImageId=FindInMap('PaAmiRegionMap', Ref('AWS::Region'), 'AMI'), InstanceType=variables['InstanceType'].ref, KeyName=variables['KeyName'].ref, Monitoring=variables['DetailedMonitoring'].ref, NetworkInterfaces=networkinterfaces, Tags=Tags(variables['Tags']), Tenancy=variables['PlacementTenancy'].ref, )) template.add_output( Output('{}Id'.format(ec2instance.title), Description='ID of EC2 Instance created', Export=Export( Sub('${AWS::StackName}-%sId' % ec2instance.title)), Value=Ref(ec2instance)))
def add_security_group(self, name, ingress_rules, vpc, description='Description not supplied', egress_rules=[]): """ Create a Security Group :param name: Name of the SG :param ingress_rules: Ingress rules :param vpc: VPC ID to put the SG in :param description: Description of the SG :param egress_rules: Egress rules """ self.template.add_resource( ec2.SecurityGroup(name, GroupDescription=description, SecurityGroupIngress=ingress_rules, SecurityGroupEgress=egress_rules, VpcId=vpc, Tags=[{ 'Key': 'Name', 'Value': name }])) self.template.add_output( Output(name, Value=Ref(name), Description=u"Security group details for {}".format(name), Export=Export(Sub("${AWS::StackName}-" + name))))
def add_resources(self): """Add resources to template.""" template = self.template variables = self.get_variables() template.add_condition( 'ProtoIsHttps', Equals(variables['ListeningProtocol'].ref, 'HTTPS')) listener = template.add_resource( elasticloadbalancingv2.Listener( 'AlbListener', Certificates=If('ProtoIsHttps', [ elasticloadbalancingv2.Certificate( CertificateArn=variables['AcmCertArn'].ref) ], Ref('AWS::NoValue')), DefaultActions=[ elasticloadbalancingv2.Action( TargetGroupArn=variables['DefaultTargetGroupArn'].ref, Type='forward') ], LoadBalancerArn=variables['AlbArn'].ref, Port=variables['ListeningPort'].ref, Protocol=variables['ListeningProtocol'].ref, SslPolicy=If('ProtoIsHttps', variables['SslPolicy'].ref, Ref('AWS::NoValue')))) template.add_output( Output("{}Arn".format(listener.title), Description="ARN of the Listener", Value=Ref(listener), Export=Export( Sub('${AWS::StackName}-%sArn' % listener.title))))
def __init__(self, groups, roles, users): super(Outputs, self).__init__() self.EC2BaselineProfile = Output( "EC2BaselineProfile", Description= "Allows EC2 instances to use the role created by this stack", Value=Ref(users.EC2BaselineProfile), Export=Export("iam-role-ec2-baseline")) self.ECSClusterServiceRole = Output( "ECSClusterServiceRole", Description= "Allows ECS services to use the role created by this stack", Value=Ref(roles.ECSClusterServiceRole), Export=Export("iam-role-ecs-service"))
def add_group(c, GroupName, model, named=False, PolicyDocument=None): cfn_name = c.scrub_name(GroupName + "Group") kw_args = {"Path": "/", "ManagedPolicyArns": []} if named: kw_args["GroupName"] = GroupName if "managed_policies" in model: kw_args["ManagedPolicyArns"] = policy.parse_managed_policies( c, model["managed_policies"], GroupName) if "inline_policies" in model: kw_args["Policies"] = policy.add_inline_policy( c, GroupName, PolicyDocument, ) if "retain_on_delete" in model: if model["retain_on_delete"] is True: kw_args["DeletionPolicy"] = "Retain" c.template[c.current_account].add_resource( Group(c.scrub_name(cfn_name), **kw_args)) if c.config['global']['template_outputs'] == "enabled": c.template[c.current_account].add_output([ Output(cfn_name + "Arn", Description="Group " + GroupName + " ARN", Value=GetAtt(cfn_name, "Arn"), Export=Export(Sub("${AWS::StackName}-" + cfn_name + "Arn"))) ])
def add_resources(self): """Add resources to template.""" template = self.template variables = self.get_variables() listenerrule = template.add_resource( elasticloadbalancingv2.ListenerRule( 'ListenerRule', Actions=[ elasticloadbalancingv2.Action( TargetGroupArn=variables['TargetGroupArn'].ref, Type='forward' ) ], Conditions=[ elasticloadbalancingv2.Condition( Field=variables['Condition'].ref, Values=[variables['Value'].ref] ) ], ListenerArn=variables['ListenerArn'].ref, Priority=variables['Priority'].ref ) ) template.add_output(Output( "{}Arn".format(listenerrule.title), Description="ARN of the Listener Rule", Value=Ref(listenerrule), Export=Export( Sub('${AWS::StackName}-%sArn' % listenerrule.title) ) ))
def add_public_subnet_c_output(self): self.public_net_output = self.template.add_output(Output( "PublicSubnetC", Export=Export(Sub("${AWS::StackName}-PublicSubnetC")), Description="Public subnet network range", Value=Ref("PublicSubnetC"), ))
def create_instance_profile(c, RoleName, model, named=False): cfn_name = scrub_name(RoleName + "InstanceProfile") kw_args = { "Path": "/", "Roles": [Ref(scrub_name(RoleName + "Role"))] } if named: kw_args["InstanceProfileName"] = RoleName if "retain_on_delete" in model: if model["retain_on_delete"] is True: kw_args["DeletionPolicy"] = "Retain" c.template[c.current_account].add_resource(InstanceProfile( cfn_name, **kw_args )) if c.config['global']['template_outputs'] == "enabled": c.template[c.current_account].add_output([ Output( cfn_name + "Arn", Description="Instance profile for Role " + RoleName + " ARN", Value=Ref(cfn_name), Export=Export(Sub("${AWS::StackName}-" + cfn_name + "Arn")) ) ])
def add_cloudtrail(c, TrailName, model, named=False): cfn_name = c.scrub_name(TrailName + "Trail") kw_args = {"IncludeGlobalServiceEvents": True} if named: kw_args["TrailName"] = TrailName if "logging" in model: kw_args["IsLogging"] = model["logging"] if "bucket" in model: kw_args["DependsOn"] = c.scrub_name(model["bucket"] + "Bucket") kw_args["S3BucketName"] = model["bucket"] if "multiregion" in model: kw_args["IsMultiRegionTrail"] = model["multiregion"] if "GlobalEvents" in model: kw_args["IncludeGlobalServiceEvents"] = model["GlobalEvents"] _LOGGER.debug("Adding Trail to :{}".format(c.current_account)) c.template[c.current_account].add_resource(Trail(cfn_name, **kw_args)) if c.config['global']['template_outputs'] == "enabled": c.template[c.current_account].add_output([ Output(cfn_name + "Arn", Description="Bucket " + TrailName + " ARN", Value=GetAtt(cfn_name, "Arn"), Export=Export(Sub("${AWS::StackName}-" + cfn_name + "Arn"))) ])
def add_user(c, UserName, model, named=False): cfn_name = scrub_name(UserName + "User") kw_args = { "Path": "/", "Groups": [], "ManagedPolicyArns": [], "Policies": [], } if named: kw_args["UserName"] = UserName if "groups" in model: kw_args["Groups"] = parse_imports(c, model["groups"]) if "managed_policies" in model: kw_args["ManagedPolicyArns"] = parse_managed_policies( c, model["managed_policies"], UserName) if "password" in model: kw_args["LoginProfile"] = LoginProfile(Password=model["password"], PasswordResetRequired=True) if "retain_on_delete" in model: if model["retain_on_delete"] is True: kw_args["DeletionPolicy"] = "Retain" c.template[c.current_account].add_resource(User(cfn_name, **kw_args)) if c.config['global']['template_outputs'] == "enabled": c.template[c.current_account].add_output([ Output(cfn_name + "Arn", Description="User " + UserName + " ARN", Value=GetAtt(cfn_name, "Arn"), Export=Export(Sub("${AWS::StackName}-" + cfn_name + "Arn"))) ])
def add_role(c, RoleName, model, named=False): cfn_name = scrub_name(RoleName + "Role") kw_args = { "Path": "/", "AssumeRolePolicyDocument": build_role_trust(c, model['trusts']), "ManagedPolicyArns": [], "Policies": [] } if named: kw_args["RoleName"] = RoleName if "managed_policies" in model: kw_args["ManagedPolicyArns"] = parse_managed_policies( c, model["managed_policies"], RoleName) if "retain_on_delete" in model: if model["retain_on_delete"] is True: kw_args["DeletionPolicy"] = "Retain" c.template[c.current_account].add_resource(Role(cfn_name, **kw_args)) if c.config['global']['template_outputs'] == "enabled": c.template[c.current_account].add_output([ Output(cfn_name + "Arn", Description="Role " + RoleName + " ARN", Value=GetAtt(cfn_name, "Arn"), Export=Export(Sub("${AWS::StackName}-" + cfn_name + "Arn"))) ])
def add_resources_and_output(self): """Add resources to template.""" template = self.template variables = self.get_variables() ec2securitygroup = template.add_resource( ec2.SecurityGroup('Sg', GroupName=variables['SgName'].ref, GroupDescription=variables['SgDescription'].ref, Tags=Tags(variables['Tags']), VpcId=variables['VpcId'].ref)) for rule, settings in variables['Rules'].iteritems(): if 'IpProtocol' not in settings.keys(): settings['IpProtocol'] = 'tcp' template.add_resource( ec2.SecurityGroupIngress( 'SgIngress{}'.format(sub('[/.-]', '', rule)), GroupId=GetAtt(ec2securitygroup, 'GroupId'), **settings)) template.add_output( Output('{}Id'.format(ec2securitygroup.title), Description='ID of the Security Group created', Value=GetAtt(ec2securitygroup, 'GroupId'), Export=Export( Sub('${AWS::StackName}-%sId' % ec2securitygroup.title))))
def __create_load_balancer(): template = Template() load_balancer = template.add_resource(resource=LoadBalancer( title='SampleFargateLoadBalancer', Name='sample-fargate-load-balancer', Subnets=[ ImportValue(CommonResource.ExportName.PUBLIC_SUBNET_A_ID.value), ImportValue(CommonResource.ExportName.PUBLIC_SUBNET_B_ID.value) ], SecurityGroups=[ImportValue(ExportName.ALB_SECURITY_GROUP.value)], Scheme='internet-facing')) target_group = template.add_resource(resource=TargetGroup( title='SampleFargateTargetGroup', Port=80, Protocol='HTTP', TargetType='ip', VpcId=ImportValue(CommonResource.ExportName.VPC_ID.value))) template.add_output(output=Output(title=target_group.title, Value=Ref(target_group), Export=Export( name=ExportName.TARGET_GROUP.value))) template.add_resource(resource=Listener( title='SampleFargateListener', DefaultActions=[ Action(Type='forward', TargetGroupArn=Ref(target_group)) ], LoadBalancerArn=Ref(load_balancer), Port=80, Protocol='HTTP')) output_template_file(template, 'alb.yml') return target_group
def add_vpc_output(self): self.vpc_output = self.template.add_output(Output( "VPCId", Export=Export(Sub("${AWS::StackName}-VPCId")), Description="VPCId of vpc", Value=Ref(self.vpc), ))
def __init__(self, leaf_title, availability_zones, template, tree_name, database_config): """ Create an RDS as a leaf, part of cross referenced stack :param leaf_title: title of the API Gateway as part of cross referenced stack :param availability_zones: List of availability zones RDS resources can use :param tree_name: name of cross referenced stack :param template: Troposphere stack to append resources to :param database_config: object containing database related variables """ self.leaf_title = leaf_title self.availability_zones = availability_zones self.tree_name = tree_name self.tree_config = None self.set_tree_config(template=template, availability_zones=availability_zones, tree_name=tree_name) self.tree_config.private_hosted_zone_id = ImportValue( self.tree_name + '-PrivateHostedZoneId') self.tree_config.private_hosted_zone_domain = ImportValue( self.tree_name + '-PrivateHostedZoneDomain') super(DatabaseLeaf, self).__init__(template=template, title=leaf_title, network_config=self.tree_config, database_config=database_config) self.template.add_output( Output('rdsSecurityGroup', Description='RDS Security group', Value=self.security_group, Export=Export(self.tree_name + '-' + self.leaf_title + '-SecurityGroup')))
def addFunction( path: str , template: Template , stackname: str , stage: str , src: Source ) -> Template: ''' Takes a prefix & adds the lambda function to the template ''' config = loadConfig(path) name = config["Name"] iam_role = getIAM(path, name, stackname, stage) template.add_resource(iam_role) env_vars = {} for key, value in getEnvVars(path, name, stage).items(): env_vars[key] = value func = getLambda(name, src, iam_role, stackname, stage, env_vars, config) func_ref = template.add_resource(func) alias = getFunctionAlias(path, name, GetAtt(func_ref,"Arn"), stackname, stage) if alias is not None: template.add_resource(alias) template.add_output([ Output( toAlphanum(name + stackname + stage) , Value = GetAtt(func_ref, "Arn") , Export = Export(name + stackname + stage) , Description = stage +": ARN for Lambda Function" )]) return template
def add_resources(self): """Add resources to template.""" template = self.template # Elastic IPs vpnelasticip = template.add_resource( ec2.EIP('VPNElasticIP', Domain='vpc')) template.add_output([ Output('VpnEipPublicIp', Description='VPN instance public IP', Export=Export(Sub('${AWS::StackName}-VpnEipPublicIp')), Value=Ref(vpnelasticip)), Output('VpnEipAllocationId', Description='AllocationId of the VPN instance public IP', Export=Export(Sub('${AWS::StackName}-VpnEipAllocationId')), Value=GetAtt(vpnelasticip, 'AllocationId')) ])
def add_private_net_output(self): self.private_net_output = self.template.add_output( Output( "PrivateSubnet", Export=Export(Sub("${AWS::StackName}-PrivateSubnet")), Description="Private subnet network range", Value=Ref("PrivateSubnet"), ))
def o_bucket_arn(self): _id = 'BucketArn' return Output( _id, Description='The ARN of the S3 bucket', Value=GetAtt(self.r_bucket, 'Arn'), # We're exporting the output as <StackName>-<OutputName> # Other stacks can consume the output value using the same naming Export=Export(Sub("${AWS::StackName}-%s" % _id)))
def define_export_name(self, output_definition, attribute_parameter): """ Method to define the export name for the resource :return: """ if len(output_definition) == 5 and output_definition[4]: LOG.debug(f"Adding portback output for {self.name}") export = Export( Sub( f"${{STACK_NAME}}{DELIM}{self.name}{DELIM}{output_definition[4]}", STACK_NAME=define_stack_name(), )) else: export = Export( Sub( f"${{STACK_NAME}}{DELIM}{self.logical_name}{DELIM}{attribute_parameter.title}", STACK_NAME=define_stack_name(), ), ) return export
def add_outputs(self): ''' Add outputs to generated template ''' self.cfn_template.add_output( Output( constants.SERVICE, Description="ECS Service", Export=Export(Sub('${Environment}-SERVICE')), Value=Ref(constants.SERVICE), )) self.cfn_template.add_output( Output( constants.TASK, Description="ECS Task", Export=Export(Sub('${Environment}-TASK')), Value=Ref(constants.TASK), )) return self.cfn_template
def o_bucket_arn(self): _id = 'BucketArn' return Output( _id, Description='The ARN of the S3 bucket', Value=GetAtt(self.r_bucket, 'Arn'), # We're exporting the output as <StackName>-<OutputId> # Other stacks can read the output relying on the same convention Export=Export(Sub("${AWS::StackName}-%s" % _id)) )
def S3BucketTemplate(name, app, env): template = Template() s3Bucket = template.add_resource(Bucket("S3Bucket" + name + app + env, )) output = template.add_output( Output("Bucket" + name + app + env, Value=Ref("S3Bucket" + name + app + env), Export=Export("Bucket" + name + app + env))) return (template.to_json())
def __init__(self, config_file): # Read our YAML with open(config_file, 'r') as stream: self.config = yaml.load(stream, Loader=yaml.FullLoader) # We will use our current timestamp in UTC as our build version self.build_version = \ datetime.datetime.utcnow().strftime("%Y-%m-%dZ%H:%M:%S") # To hold our Troposphere template objects self.template = {} # A list of our accounts by names and IDs. self.account_ids = [] self.account_names = [] # A hash of IDs to names to help in forward and reverse resolution. self.account_map_ids = {} self.account_map_names = {} # Our parent account. self.parent = "" # SAML Provider self.saml_provider = "" for account in self.config['accounts']: account_id = str(self.config['accounts'][account]['id']) # Append to our array of account IDS: self.account_ids.append(account_id) self.account_names.append(account) self.account_map_names[account_id] = account self.account_map_ids[account] = account_id self.template[account] = Template() self.template[account].add_version("2010-09-09") self.template[account].add_description( "Build " + self.build_version + " - IAM Users, Groups, Roles, and Policies for account " + account + " (" + self.account_map_ids[account] + ")" ) self.template[account].add_output([ Output( "TemplateBuild", Description="CloudFormation Template Build Number", Value=self.build_version, Export=Export(Sub("${AWS::StackName}-" + "TemplateBuild")) ) ]) if "parent" in self.config['accounts'][account]: if self.config['accounts'][account]['parent'] is True: self.parent_account = account self.parent_account_id = account_id if "saml_provider" in self.config['accounts'][account]: self.saml_provider = \ self.config['accounts'][account]["saml_provider"] if self.parent_account == "": raise Exception( "No account is marked as parent in the configuration file. " "One account should have parent: true" )