def test_package(): tpl_tier11 = Template(Metadata={"Description": "Tier 1-1"}, ) restapi = apigateway.RestApi( "RestApi", template=tpl_tier11, Name="troposphere-mate-test", ) tpl_tier1 = Template(Metadata={"Description": "Tier 1"}, ) nest_stack_tier11 = cloudformation.Stack( "NestedTemplate", template=tpl_tier1, TemplateURL="", ) link_stack_template( stack=nest_stack_tier11, template=tpl_tier11, ) tpl_master = Template(Metadata={"Description": "Master Tier"}, ) nest_stack_tier1 = cloudformation.Stack( "NestedTemplate", template=tpl_master, TemplateURL="", ) link_stack_template( stack=nest_stack_tier1, template=tpl_tier1, ) template_url = package(s3_client=s3_client, template=tpl_master, bucket_name=bucket_name, verbose=True) print(template_url)
def create_apigw_method(self, template: Template): if self.apigw_method_aws_object_ready(): template.add_resource(self.apigw_method_aws_object, ignore_duplicate=True) if self.apigw_method_lbd_permission_aws_object_ready(): template.add_resource(self.apigw_method_lbd_permission_aws_object, ignore_duplicate=True)
class CannedCommonEc2IamRole(MultiEnvBasicConfig): template = None # type: Template iam_role_ec2_s3_full_access = None # type: iam.Role iam_instance_profile_ec2_s3_full_access = None # type: iam.Role def create_template(self): self.template = Template() self.param_env_name = param_env_name self.param_env_name.Default = self.ENVIRONMENT_NAME.get_value() self.template.add_parameter(param_env_name) self.iam_role_ec2_s3_full_access = iam.Role( "IamRoleEc2S3FullAccess", template=self.template, RoleName=helper_fn_sub("{}-ec2-s3-full-access", self.param_env_name), AssumeRolePolicyDocument=create_assume_role_policy_document( [AWSServiceName.amazon_Elastic_Compute_Cloud_Amazon_EC2]), ManagedPolicyArns=[AWSManagedPolicyArn.amazonS3FullAccess]) self.iam_instance_profile_ec2_s3_full_access = iam.InstanceProfile( "IamInstanceProfileS3FullAccess", template=self.template, InstanceProfileName=helper_fn_sub("{}-ec2-s3-full-access", self.param_env_name), Roles=[ self.iam_role_ec2_s3_full_access.iam_role_name, ]) return self.template
def test_from_dict(self): from troposphere_mate.apigateway import RestApi tpl = Template() rest_api = RestApi( "RestApi", template=tpl, Metadata={"description": "a rest api"}, Name="MyApi", ) output_rest_api_id = Output("RestApiId", Value=Ref(rest_api), DependsOn=rest_api) tpl.add_output(output_rest_api_id) dct = tpl.to_dict() # print(tpl.to_json()) tpl = Template.from_dict(dct) tpl.remove_resource_by_label(label="na") assert tpl.to_dict() == dct assert isinstance(tpl.resources["RestApi"], RestApi) assert isinstance(tpl.outputs["RestApiId"], Output) assert getattr( tpl.outputs[output_rest_api_id.title], mtdt.TemplateLevelField.OUTPUTS_DEPENDS_ON, ) == [ rest_api.title, ] assert tpl.to_dict() == dct
def create_s3_event_bucket(self, template: Template): if self.s3_event_bucket_aws_object_ready(): template.add_resource(self.s3_event_bucket_aws_object, ignore_duplicate=True) if self.s3_event_bucket_lbd_permission_aws_object_ready(): template.add_resource( self.s3_event_bucket_lbd_permission_aws_object, ignore_duplicate=True)
def create_scheduled_job_event(self, template: Template): if self.scheduled_job_event_rule_aws_objects_ready(): for _, value in self.scheduled_job_event_rule_aws_objects.items(): template.add_resource(value, ignore_duplicate=True) if self.scheduled_job_event_lbd_permission_aws_objects_ready(): for _, value in self.scheduled_job_event_lbd_permission_aws_objects.items( ): template.add_resource(value, ignore_duplicate=True)
def test_deploy_stack(): # tier11 tpl_tier11 = Template(Metadata={"Description": "Tier 1-1"}, ) restapi = apigateway.RestApi( "RestApi", template=tpl_tier11, Name="troposphere-mate-test", ) # tier1 tpl_tier1 = Template(Metadata={"Description": "Tier 1"}, ) nest_stack_tier11 = cloudformation.Stack( "NestedStackTier11", template=tpl_tier1, TemplateURL="", ) # link link_stack_template( stack=nest_stack_tier11, template=tpl_tier11, ) # master tpl_master = Template(Metadata={"Description": "Master Tier"}, ) nest_stack_tier1 = cloudformation.Stack( "NestedStackTier1", template=tpl_master, TemplateURL="", ) link_stack_template( stack=nest_stack_tier1, template=tpl_tier1, ) stack_manager = StackManager( boto_ses=boto_ses, cft_bucket=bucket_name, ) stack_manager.deploy(template=tpl_master, ) template_url = package(s3_client=s3_client, template=tpl_master, bucket_name=bucket_name, verbose=True) deploy_stack( cf_client=cf_client, stack_name="troposphere-mate-stack-deploy-test", template_url=template_url, stack_tags={"Creator": "Sanhe"}, )
def test_upload_template(): template = Template() restapi = apigateway.RestApi( "RestApi", template=template, Name="troposphere-mate-test", ) template_url = upload_template( s3_client=s3_client, template_content=template.to_json(indent=4, sort_keys=True), bucket_name=bucket_name, ) print(template_url)
def do_create_template(self, **kwargs): template = Template() self.template = template self.bucket = s3.Bucket( "S3Bucket", template=template, BucketName="my-bucket", ) return self.template
def __init__(self): self.tpl = Template() self.param_env_name = Parameter("EnvName", Type="String") self.rest_api_x = apigateway.RestApi( "RestApiX", template=self.tpl, Name="MyRestApiX", ) self.rest_api_y = apigateway.RestApi( "RestApiY", template=self.tpl, Name="MyRestApiY", DependsOn=self.rest_api_x, ) self.rest_api_z = apigateway.RestApi("RestApiZ", template=self.tpl, Name="MyRestApiZ", DependsOn=self.rest_api_y) self.output_rest_api_x_id = Output( "RestApiXId", Value=Ref(self.rest_api_x), DependsOn=self.rest_api_x, ) self.tpl.add_output(self.output_rest_api_x_id) self.output_rest_api_y_id = Output( "RestApiYId", Value=Ref(self.rest_api_y), DependsOn=self.rest_api_y, ) self.tpl.add_output(self.output_rest_api_y_id) self.output_rest_api_z_id = Output( "RestApiZId", Value=Ref(self.rest_api_z), DependsOn=self.rest_api_z, ) self.tpl.add_output(self.output_rest_api_z_id)
def test_tags(): """ .. note:: ``my_bucket.Tags = [{"Key": "Creator", "Value": "Alice"},]`` method doesn't work anymore in troposphere. """ from troposphere_mate import s3 tpl = Template() my_bucket = s3.Bucket("MyBucket", template=tpl, BucketName="my-bucket", Tags=Tags(Creator="Alice")) assert tpl.to_dict()["Resources"]["MyBucket"]["Properties"]["Tags"] == [{ "Key": "Creator", "Value": "Alice" }]
def test_initiate_default_template_metadata(): tpl = Template() mtdt.initiate_default_template_metadata(tpl) validate_template_level_basic_fields(tpl) tpl = Template(Metadata={"Key": "Value"}) mtdt.initiate_default_template_metadata(tpl) validate_template_level_basic_fields(tpl) assert tpl.metadata["Key"] == "Value" tpl = Template( Metadata={mtdt.TROPOSPHERE_METADATA_FIELD_NAME: { "Key": "Value" }}) mtdt.initiate_default_template_metadata(tpl) validate_template_level_basic_fields(tpl) assert tpl.metadata[mtdt.TROPOSPHERE_METADATA_FIELD_NAME]["Key"] == "Value" tpl = Template(Metadata=[1, 2, 3]) with pytest.raises(TypeError): mtdt.initiate_default_template_metadata(tpl) with pytest.raises(TypeError): mtdt.initiate_default_resource_metadata(tpl)
def test_package_with_simple_template(): template = Template() restapi = apigateway.RestApi( "RestApi", template=template, Name="troposphere-mate-test", ) template_url = package( s3_client=s3_client, template=template, bucket_name=bucket_name, ) print(template_url)
def test_update_tags(self): from troposphere_mate import ec2 # overwrite=False works tpl = Template() my_vpc = ec2.VPC("MyVPC", template=tpl, CidrBlock="10.0.0.0/16", Tags=Tags(Creator="Alice")) my_sg = ec2.SecurityGroup( "MySG", template=tpl, GroupDescription="My", GroupName="MySG", VpcId=Ref(my_vpc), ) my_subnet = ec2.Subnet( "MySubnet", template=tpl, CidrBlock="10.0.1.0/24", VpcId=Ref(my_vpc), ) def get_name(resource, project): if resource.resource_type == "AWS::EC2::SecurityGroup": return "{}/sg/{}".format(project, resource.GroupName) tpl.update_tags(dict(Project="my-project"), overwrite=False) tpl.update_tags(tags_dct=dict( Name=functools.partial(get_name, project="my-project"), Creator="Bob", ), overwrite=False) assert tags_list_to_dct( tpl.to_dict()["Resources"]["MyVPC"]["Properties"]["Tags"]) == dict( Project="my-project", Creator="Alice", ) assert tags_list_to_dct( tpl.to_dict()["Resources"]["MySG"]["Properties"]["Tags"]) == dict( Project="my-project", Name="my-project/sg/MySG", Creator="Bob", )
def create_template(app): """ :type app: AppConfig :rtype: Template """ template = Template() for repo in app.repos: if repo.repo_registry != AppConfig.Options.RepoRegistry.aws_ecr: continue ecr.Repository( f"Repository{camelcase(repo.repo_name)}", template=template, RepositoryName=repo.repo_name, LifecyclePolicy=ecr. LifecyclePolicy(LifecyclePolicyText=json.dumps({ "rules": [{ "rulePriority": 1, "description": "Expire images older than 14 days", "selection": { "tagStatus": "untagged", "countType": "sinceImagePushed", "countUnit": "days", "countNumber": repo.repo_aws_ecr_life_cycle_expire_days }, "action": { "type": "expire" } }] })), DeletionPolicy="Retain", ) common_tags = dict(ProjectName=app.app_name, ) template.update_tags(common_tags) return template
def test_stack_manager(): """ First time, run stack_manager.deploy, comment out stack_manager.delete Second time, comment out stack_manager.deploy, run stack_manager.delete. """ stack_name = "troposphere-mate-stack-manager-test" template = Template() apigateway.RestApi( "RestApi", template=template, Name="troposphere-mate-test", ) stack_manager.deploy( template, stack_name=stack_name, )
def test_remove_resource_by_label(self): from troposphere_mate import s3 tpl = Template() bucket1 = s3.Bucket( "Bucket1", template=tpl, BucketName="bucket1", Metadata={DEFAULT_LABELS_FIELD: ["tier1", "tier_bucket"]}) bucket2 = s3.Bucket( "Bucket2", template=tpl, BucketName="bucket2", Metadata={DEFAULT_LABELS_FIELD: ["tier2", "tier_bucket"]}) bucket3 = s3.Bucket( "Bucket3", template=tpl, BucketName="bucket3", Metadata={DEFAULT_LABELS_FIELD: ["tier3", "tier_bucket"]}) assert len(tpl.resources) == 3
def test_create_resource_type_label(self): from troposphere_mate import s3, apigateway tpl = Template() s3_bucket = s3.Bucket( "Bucket", template=tpl, BucketName="my-bucket", ) rest_api = apigateway.RestApi("RestApi", template=tpl, DependsOn=[ s3_bucket, ]) tpl.create_resource_type_label() tpl.create_resource_type_label() # see if second call raise exception assert len(tpl.to_dict()["Resources"]["Bucket"]["Metadata"] [DEFAULT_LABELS_FIELD]) == 1 assert len(tpl.to_dict()["Resources"]["RestApi"]["Metadata"] [DEFAULT_LABELS_FIELD]) == 1
from troposphere_mate import ( Template, Parameter, Ref, helper_fn_sub, canned, ecr, ecs, iam, elasticloadbalancingv2, ec2, ) from ..devops.config_init import config template = Template() param_project_name = Parameter("ProjectName", Type="String", Default=config.PROJECT_NAME.get_value()) param_project_name_slug = Parameter( "ProjectNameSlug", Type="String", Default=config.PROJECT_NAME_SLUG.get_value()) param_stage = Parameter("Stage", Type="String", Default=config.STAGE.get_value()) param_env_name = Parameter("EnvironmentName",
def create_lbd_func(self, template: Template): if self.lbd_func_aws_object_ready(): template.add_resource(self.lbd_func_aws_object, ignore_duplicate=True)
# -*- coding: utf-8 -*- import pytest from pytest import raises, approx from troposphere_mate.core.orch_core import ResourceFilter from troposphere_mate import Template, s3, cloudformation tpl = Template() cloudformation.Stack( "T1", template=tpl, TemplateURL="./01-tier.json", ) cloudformation.Stack( "T2", template=tpl, TemplateURL="./02-tier.json", ) class TestResourceFilter(object): def test(self): pass if __name__ == "__main__": import os basename = os.path.basename(__file__)
GetAtt, helper_fn_sub, Ref, Export, iam, cloudformation, link_stack_template, ) # IMPORTANT! # import the nested stack python module, # allows to cross reference parameter or output and # bind "AWS::Cloudformation::Stack" with nested stack template from . import tier_1_iam_role template = Template() param_env_name = Parameter( "EnvironmentName", Type="String", ) template.add_parameter(param_env_name) iam_role_stack = cloudformation.Stack( "IamRoleStack", template=template, TemplateURL="", # cross reference parameter Parameters={ tier_1_iam_role.param_env_name.title: Ref(param_env_name),
def create_apigw_resource(self, template: Template): if self.apigw_resource_aws_object_ready(): template.add_resource(self.apigw_resource_aws_object, ignore_duplicate=True)
firehose, helper_fn_sub, Ref, Sub, AWS_ACCOUNT_ID, glue, upload_template, deploy_stack, ) from troposphere_mate.canned.iam import ( create_assume_role_policy_document, AWSServiceName, AWSManagedPolicyArn, ) template = Template() param_env_name = Parameter( "EnvironmentName", Type="String", ) # Input Stream kinesis_input_stream = kinesis.Stream( "KinesisInputStream", template=template, Name=helper_fn_sub("{}-web-event", param_env_name), RetentionPeriodHours=24, ShardCount=1, )
def test_iter_nested_template_edge_case(self): tpl = Template() assert tpl.iter_nested_template(depth_first=True) == [] assert tpl.iter_nested_template(depth_first=False) == []
def test_iter_nested_template(self): from troposphere_mate import apigateway, cloudformation, link_stack_template tpl_1_1 = Template(Metadata={"id": "11"}) apigateway.RestApi("RestApi", template=tpl_1_1, Name="MyRestApi") tpl_1_2 = Template(Metadata={"id": "12"}) apigateway.RestApi("RestApi", template=tpl_1_2, Name="MyRestApi") tpl_2_1 = Template(Metadata={"id": "21"}) apigateway.RestApi("RestApi", template=tpl_2_1, Name="MyRestApi") tpl_2_2 = Template(Metadata={"id": "22"}) apigateway.RestApi("RestApi", template=tpl_2_2, Name="MyRestApi") tpl_1 = Template(Metadata={"id": "1"}) stack11 = cloudformation.Stack( "Stack11", template=tpl_1, TemplateURL="", ) stack12 = cloudformation.Stack( "Stack12", template=tpl_1, TemplateURL="", ) link_stack_template(stack=stack11, template=tpl_1_1) link_stack_template(stack=stack12, template=tpl_1_2) tpl_2 = Template(Metadata={"id": "2"}) stack21 = cloudformation.Stack( "Stack21", template=tpl_2, TemplateURL="", ) stack22 = cloudformation.Stack( "Stack22", template=tpl_2, TemplateURL="", ) link_stack_template(stack=stack21, template=tpl_2_1) link_stack_template(stack=stack22, template=tpl_2_2) tpl = Template(Metadata={"id": "0"}) stack1 = cloudformation.Stack( "Stack1", template=tpl, TemplateURL="", ) stack2 = cloudformation.Stack( "Stack2", template=tpl, TemplateURL="", ) link_stack_template(stack=stack1, template=tpl_1) link_stack_template(stack=stack2, template=tpl_2) assert stack1.Metadata[mtdt.TROPOSPHERE_METADATA_FIELD_NAME] \ [mtdt.ResourceLevelField.CftStack.IS_NESTED_STACK] is True assert stack2.Metadata[mtdt.TROPOSPHERE_METADATA_FIELD_NAME] \ [mtdt.ResourceLevelField.CftStack.IS_NESTED_STACK] is True import sys if sys.version_info.major >= 3: ids = [ template.metadata["id"] for template in tpl.iter_nested_template(depth_first=True) ] assert ids == ["1", "11", "12", "2", "21", "22"] ids = [ template.metadata["id"] for template in tpl.iter_nested_template(depth_first=False) ] assert ids == ["1", "2", "11", "12", "21", "22"]
def test_mutable_aws_object(): """ 确定 ``mate.AWSObject`` 变化时, 对应的 ``mate.AWSObject.aws_object`` 也应该 跟着变化. """ from troposphere_mate import iam tpl = Template() my_policy = iam.ManagedPolicy( title="MyPolicy", template=tpl, PolicyDocument={}, ) my_role = iam.Role( title="MyRole", template=tpl, RoleName="my-role", AssumeRolePolicyDocument={}, ) assert tpl.to_dict( )["Resources"]["MyRole"]["Properties"]["RoleName"] == "my-role" assert "ManagedPolicyArns" not in tpl.to_dict( )["Resources"]["MyRole"]["Properties"] my_role.RoleName = "my-role-two" my_role.ManagedPolicyArns = [Ref(my_policy)] assert tpl.to_dict( )["Resources"]["MyRole"]["Properties"]["RoleName"] == "my-role-two" assert tpl.to_dict( )["Resources"]["MyRole"]["Properties"]["ManagedPolicyArns"] == [{ "Ref": "MyPolicy" }] outputs = [ Output( "MyRolePath", Value=GetAtt(my_role, "Path"), DependsOn=my_role, ) ] for output in outputs: tpl.add_output(output) assert tpl.to_dict()["Outputs"]["MyRolePath"]["Value"] == { "Fn::GetAtt": ["MyRole", "Path"] } dct = tpl.to_dict() tpl2 = Template() tpl2.add_resource(my_policy) tpl2.add_resource(my_role) for output in outputs: tpl2.add_output(output) dct2 = tpl2.to_dict() assert dct == dct2
def create_apigw_method_options_for_cors(self, template: Template): if self.apigw_method_options_for_cors_aws_object_ready(): template.add_resource( self.apigw_method_options_for_cors_aws_object, ignore_duplicate=True)
def test_remove_parameter_and_output(self): tpl = Template() p1 = Parameter("P1", Type="string") o1 = Output("O1", Value=Ref("P1")) # before state tpl.add_parameter(p1) tpl.add_output(o1) assert len(tpl.parameters) == 1 assert len(tpl.outputs) == 1 # test remove by object tpl.remove_parameter(p1) tpl.remove_output(o1) assert len(tpl.parameters) == 0 assert len(tpl.outputs) == 0 # before state tpl.add_parameter(p1) tpl.add_output(o1) assert len(tpl.parameters) == 1 assert len(tpl.outputs) == 1 # test remove by str tpl.remove_parameter(p1.title) tpl.remove_output(o1.title) assert len(tpl.parameters) == 0 assert len(tpl.outputs) == 0
def test_add_parameter_resource_output(self): from troposphere_mate import apigateway tpl = Template() param_project_name = Parameter("ProjectName", Type="String") rest_api = apigateway.RestApi( "RestApi", template=tpl, Name=Ref(param_project_name), EndpointConfiguration=apigateway.EndpointConfiguration( Types=["REGIONAL"])) output_rest_api_id = Output("RestApiId", Value=Ref(rest_api)) # test ignore_duplicate argument tpl.add_parameter(param_project_name) with raises(ValueError): tpl.add_parameter(param_project_name) tpl.add_parameter(param_project_name, ignore_duplicate=True) with raises(ValueError): tpl.add_resource(rest_api) tpl.add_resource(rest_api, ignore_duplicate=True) tpl.add_output(output_rest_api_id) with raises(ValueError): tpl.add_output(output_rest_api_id) tpl.add_output(output_rest_api_id, ignore_duplicate=True)