def create_launch_template(self): web_sg_list = [self.web_sg_id] launch_template = self.tpl.add_resource( ec2.LaunchTemplate( 'LaunchTemplate', LaunchTemplateName=f'{self.prefix}-{self.project}-LaunchTemplate', LaunchTemplateData=ec2.LaunchTemplateData( ImageId=self.image_id, InstanceType=self.instance_type, KeyName=self.key_name, SecurityGroupIds=web_sg_list ) ) ) # 起動テンプレートの論理IDをアウトプット self.tpl.add_output( Output( 'LaunchTemplateId', Description='LaunchTemplate Id', Value=Ref(launch_template) ) ) # 起動テンプレートのバージョンをアウトプット self.tpl.add_output( Output( 'LaunchTemplateLatestVersion', Description='LaunchTemplate Latest Version', Value=GetAtt(launch_template, 'LatestVersionNumber') ) )
def create_vpc_base(self): # VPCを作成 vpc = self.tpl.add_resource( ec2.VPC('Vpc', CidrBlock=self.vpc_cidr_block, EnableDnsSupport=True, EnableDnsHostnames=True, Tags=[Tag('Name', f'{self.prefix}-{self.project}-vpc')])) # VPCの論理IDをoutputする self.tpl.add_output( Output('VpcId', Description='VpcId', Value=Ref(vpc))) # VPCのCidrBlockをoutputする self.tpl.add_output( Output('VpcCidr', Description='VPC Cidr Block', Value=self.vpc_cidr_block)) # InternetGatewayを作成 igw = self.tpl.add_resource(ec2.InternetGateway('Igw')) # InternetGatewayの論理IDをoutputする self.tpl.add_output( Output('IgwId', Description='Internet Gateway Id', Value=Ref(igw))) # InternetGatewayをVPCにアタッチする self.tpl.add_resource( ec2.VPCGatewayAttachment('VpcIgwAttachment', InternetGatewayId=Ref(igw), VpcId=Ref(vpc))) return vpc, igw
def create_template(self): # ALBを作成する alb = self.tpl.add_resource( elb.LoadBalancer( 'LoadBarancer', Name=f'{self.prefix}-{self.project}-alb', LoadBalancerAttributes=[ elb.LoadBalancerAttributes(Key='access_logs.s3.enabled', Value='true'), elb.LoadBalancerAttributes(Key='access_logs.s3.bucket', Value=self.elb_log_bucket) ], Scheme='internet-facing', SecurityGroups=self.security_group_list, Subnets=self.subnet_id_list)) # ALBの論理IDをアウトプット self.tpl.add_output( Output('LoadBalancer', Description='ALB ARN', Value=Ref(alb))) # ターゲットグループを作成 target_group = self.tpl.add_resource( elb.TargetGroup('TargetGroup', HealthCheckPath='/', HealthCheckPort='80', HealthCheckProtocol='HTTP', Matcher=elb.Matcher(HttpCode='200'), Name=f'{self.prefix}-{self.project}-target-group', Port=80, Protocol='HTTP', TargetType='instance', VpcId=self.vpc_id)) # ターゲットグループの論理IDをアウトプット self.tpl.add_output( Output('TargetGroupId', Description='TargetGroup Id', Value=Ref(target_group))) # リスナーを作成 self.tpl.add_resource( elb.Listener('Listener', DefaultActions=[ elb.Action( Type='forward', TargetGroupArn=Ref(target_group), ) ], LoadBalancerArn=Ref(alb), Port=80, Protocol='HTTP'))
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)
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_db_sg(self): db_sg = self.tpl.add_resource( ec2.SecurityGroup( 'DBSG', GroupDescription='Allow DB From Any', VpcId=self.vpc_id, SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', CidrIp='0.0.0.0/0', FromPort=3306, ToPort=3306 ) ] ) ) # セキュリティグループの論理IDをアウトプットする self.tpl.add_output( Output( 'DBSGId', Description='DB Security Group Id', Value=GetAtt(db_sg, 'GroupId') ) )
def create_web_sg(self): web_sg = self.tpl.add_resource( ec2.SecurityGroup( 'WebSG', GroupDescription='Allow Web From Any', VpcId=self.vpc_id, SecurityGroupIngress=[ ec2.SecurityGroupRule( IpProtocol='tcp', CidrIp='0.0.0.0/0', FromPort=443, ToPort=443 ), ec2.SecurityGroupRule( IpProtocol='tcp', CidrIp='0.0.0.0/0', FromPort=80, ToPort=80 ), ] ) ) # セキュリティグループの論理IDをアウトプットする self.tpl.add_output( Output( 'WebSGId', Description='Web Security Group Id', Value=GetAtt(web_sg, 'GroupId') ) )
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 create_web_route(self): web_route_table = self.tpl.add_resource( ec2.RouteTable( 'WebRouteTable', VpcId=self.vpc_id, Tags=[ Tag('Name', f'{self.prefix}-{self.project}-WebRouteTable') ])) # Webのルートテーブルの論理IDをアウトプット self.tpl.add_output( Output('WebRouteTableId', Description='Web Route Table Id', Value=Ref(web_route_table))) # Webのルートテーブルにルートを追加 self.tpl.add_resource( ec2.Route('WebRoute', RouteTableId=Ref(web_route_table), DestinationCidrBlock='0.0.0.0/0', GatewayId=self.igw_id)) # Webサブネットにルートテーブルを紐つける for index, subnet_id in enumerate(self.web_subnet_list): self.tpl.add_resource( ec2.SubnetRouteTableAssociation( f'WebSubnet{index}RouteTable', RouteTableId=Ref(web_route_table), SubnetId=subnet_id))
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 test_init(self): rest_api = apigateway.RestApi("RestApi", Name="MyRestApi") output_rest_api_id = Output( "RestApiId", Value=Ref(rest_api), DependsOn=rest_api, ) assert output_rest_api_id.depends_on_resources == [ "RestApi", ] output_rest_api_id = Output( "RestApiId", Value=Ref(rest_api), DependsOn=[ rest_api, ], ) assert output_rest_api_id.depends_on_resources == [ "RestApi", ]
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 create_template(self): var = self.get_variables() project_id = var.get('ProjectId') environment = var.get('Environment') assets_bucket_name = var.get('AssetsBucketName') self.template.description = 'S3 Bucket Stack' # Front S3 Bucket assets_bucket = self.template.add_resource( s3.Bucket( 'AssetsBucket', #primary name BucketName=Join('-', [assets_bucket_name, Ref(AWS_ACCOUNT_ID)]), DeletionPolicy=Retain)) self.template.add_output(Output('AssetsBucketName', Ref(assets_bucket)))
def create_subnets(self, vpc, prefix, addr_list): subnets = [] for index, addr in enumerate(addr_list): subnets.append( self.tpl.add_resource( ec2.Subnet(f'{prefix}Subnet{index}', CidrBlock=addr, VpcId=Ref(vpc), AvailabilityZone=Select(index % get_az_count(), GetAZs( Ref(AWS_REGION))), Tags=[Tag('Name', f'{prefix}Subnet{index}')]))) # サブネットの論理IDをアウトプットする self.tpl.add_output( Output(f'{prefix}SubnetList', Description=f'{prefix} subnet list', Value=Join(',', [Ref(subnet) for subnet in subnets]))) return subnets
def create_db_route(self): db_route_table = self.tpl.add_resource( ec2.RouteTable( 'DBRouteTable', VpcId=self.vpc_id, Tags=[ Tag('Name', f'{self.prefix}-{self.project}-DBRouteTable') ])) # DBのルートテーブルの論理IDをアウトプット self.tpl.add_output( Output('DBRouteTableId', Description='DB Route Table Id', Value=Ref(db_route_table))) # DBのルートテーブルをサブネットに紐つける for index, subnet_id in enumerate(self.db_subnet_list): self.tpl.add_resource( ec2.SubnetRouteTableAssociation( f'DBSubnet{index}RouteTable', RouteTableId=Ref(db_route_table), SubnetId=subnet_id))
iam_ec2_instance_policy = iam.ManagedPolicy( "IamPolicy", template=template, ManagedPolicyName=helper_fn_sub("{}-web-server", param_env_name), PolicyDocument={ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*", "s3:Describe*", ], "Resource": "*" } ] }, ) # allow cross reference from other stack output_iam_ec2_instance_policy_name = Output( "IamInstancePolicyArn", Value=iam_ec2_instance_policy.iam_managed_policy_arn, Export=Export(helper_fn_sub("{}-iam-ec2-instance-policy-arn", param_env_name)), DependsOn=iam_ec2_instance_policy, ) template.add_output(output_iam_ec2_instance_policy_name)
def create_template(self): # ELBのログを保存する elb_log_bucket = self.tpl.add_resource( s3.Bucket( 'ElbLogBucket', BucketName=f'{self.prefix}-{self.project}-lb-log-bucket', )) # ELBの論理IDをアウトプット self.tpl.add_output( Output('ElbLogBucket', Description='LoadBalancer Log Bucket', Value=Ref(elb_log_bucket))) # ELBのログを保存させるためのBucketPolicyを作成 self.tpl.add_resource( s3.BucketPolicy( 'AlbLogPolicy', Bucket=Ref(elb_log_bucket), PolicyDocument={ 'Version': '2012-10-17', 'Statement': [{ 'Effect': 'Allow', 'Principal': { 'AWS': 'arn:aws:iam::582318560864:root' }, 'Action': 's3:PutObject', 'Resource': Sub(f'arn:aws:s3:::${{{elb_log_bucket.title}}}/AWSLogs/${{{AWS_ACCOUNT_ID}}}/*' ) }, { 'Effect': 'Allow', 'Principal': { 'Service': 'delivery.logs.amazonaws.com' }, 'Action': 's3:PutObject', 'Resource': Sub(f'arn:aws:s3:::${{{elb_log_bucket.title}}}/AWSLogs/${{{AWS_ACCOUNT_ID}}}/*' ), 'Condition': { 'StringEquals': { 's3:x-amz-acl': 'bucket-owner-full-control' } } }, { 'Effect': 'Allow', 'Principal': { 'Service': 'delivery.logs.amazonaws.com' }, 'Action': 's3:GetBucketAcl', 'Resource': Sub(f'arn:aws:s3:::${{{elb_log_bucket.title}}}') }] }))
iam_instance_profile = iam.InstanceProfile( "IamInstanceProfileWebServer", template=template, InstanceProfileName=helper_fn_sub("{}-web-server", param_env_name), # cross reference output Roles=[ GetAtt( iam_role_stack, f"Outputs.{tier_1_iam_role.output_iam_ec2_instance_role_name.title}" ), ], DependsOn=iam_role_stack, ) # allow cross reference from other stack output_iam_ec2_instance_profile_name = Output( "IamInstanceProfileName", Value=iam_instance_profile.iam_instance_profile_name, Export=Export( helper_fn_sub("{}-iam-ec2-instance-profile-name", param_env_name)), ) template.add_output(output_iam_ec2_instance_profile_name) output_iam_ec2_instance_profile_arn = Output( "IamInstanceProfileArn", Value=iam_instance_profile.iam_instance_profile_arn, Export=Export( helper_fn_sub("{}-iam-ec2-instance-profile-arn", param_env_name)), ) template.add_output(output_iam_ec2_instance_profile_arn)
def create_template(self): var = self.get_variables() self.template.description = "VPC Stack" vpc = self.template.add_resource( ec2.VPC( 'Vpc', CidrBlock=var['CidrBlock'], EnableDnsHostnames=True, EnableDnsSupport=True ) ) self.template.add_output(Output('VpcId', Ref(vpc))) internet_gateway = self.template.add_resource(ec2.InternetGateway('Igw')) self.template.add_resource( ec2.VPCGatewayAttachment( 'VpcGwAttachment', VpcId=Ref(vpc), InternetGatewayId=Ref(internet_gateway) ) ) default_route_table = self.template.add_resource( ec2.RouteTable( 'DefaultRouteTable', VpcId=Ref(vpc) ) ) self.template.add_resource( ec2.Route( 'DefaultRoute', RouteTableId=Ref(default_route_table), DestinationCidrBlock='0.0.0.0/0', GatewayId=Ref(internet_gateway) ) ) # Create Public Subnet for k, v in enumerate(var['PublicSubnets']): public_subnet = self.template.add_resource( ec2.Subnet( f'PublicSubnet{k}', CidrBlock=v, VpcId=Ref(vpc) ) ) self.template.add_output(Output(f'PublicSubnet{k}', Ref(public_subnet))) self.template.add_resource( ec2.SubnetRouteTableAssociation( f'PublicSubnetRouteTableAssociation{k}', RouteTableId=Ref(default_route_table), SubnetId=Ref(public_subnet) ) ) # Create Private Subnet for k, v in enumerate(var['PrivateSubnets']): private_subnet = self.template.add_resource( ec2.Subnet( f'PrivateSubnet{k}', CidrBlock=v, VpcId=Ref(vpc) ) ) self.template.add_output(Output(f'PrivateSubnet{k}', Ref(private_subnet)))
iam_ec_instance_role = iam.Role( "IamRoleWebServer", template=template, RoleName=helper_fn_sub("{}-web-server", param_env_name), AssumeRolePolicyDocument=canned.iam.create_assume_role_policy_document([ canned.iam.AWSServiceName.amazon_Elastic_Compute_Cloud_Amazon_EC2, ]), # cross reference output ManagedPolicyArns=[ GetAtt(iam_policy_stack, f"Outputs.{tier_1_1_iam_policy.output_iam_ec2_instance_policy_name.title}"), ], DependsOn=iam_policy_stack, ) # allow cross reference from other stack output_iam_ec2_instance_role_name = Output( "IamInstanceRoleName", Value=iam_ec_instance_role.iam_role_name, Export=Export(helper_fn_sub("{}-iam-ec2-instance-role-name", param_env_name)), DependsOn=iam_ec_instance_role, ) template.add_output(output_iam_ec2_instance_role_name) output_iam_ec2_instance_role_arn = Output( "IamInstanceRoleArn", Value=iam_ec_instance_role.iam_role_arn, Export=Export(helper_fn_sub("{}-iam-ec2-instance-role-arn", param_env_name)), DependsOn=iam_ec_instance_role, ) template.add_output(output_iam_ec2_instance_role_arn)