Instance( "AppInstance", # Incorrect interpretation from cfn2py # Metadata=Init( # { "SaltMinion": { "files": { "/tmp/init.sh": { "source": "https://s3-us-west-2.amazonaws.com/perforce-ami-us-west-2/init.sh", "mode": "0755" } }, "commands": { "setupMinion": { "command": "/tmp/init.sh 10.0.0.101 p4d-host" } } }, "configSets": { "All": ["SaltMinion"] } }, # ), Metadata=cloudformation.Metadata( cloudformation.Init( cloudformation.InitConfigSets(DeploySalt=['SaltMinion'], ), SaltMinion=cloudformation.InitConfig(commands={ "SaltMinion": { "files": { "/tmp/init.sh": { "source": "https://s3-us-west-2.amazonaws.com/perforce-ami-us-west-2/init.sh", "mode": "0755" } }, "commands": { "setupMinion": { "command": "/tmp/init.sh 10.0.0.101 app-host" } } }, "configSets": { "All": ["SaltMinion"] }, }, ), )), # Expedited Json Obj, # "AWS::CloudFormation::Init": { # "configSets": { # "All": [ # "SaltMinion" # ] # }, # "SaltMinion": { # "files": { # "/tmp/init.sh": { # "source": "https://s3-us-west-2.amazonaws.com/perforce-ami-us-west-2/init.s", # "mode": "0755" # } # }, # "commands": { # "setupMinion": { # "command": "/tmp/init.sh 10.0.0.101 p4d-host" # } # } # } # } # }, UserData=Base64( Join("", [ "#!/bin/bash -v\n", "yum update -y aws-cfn-bootstrap\n", "# Install the files and packages from the metadata\n", "\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", "\n", "# Install local config\n", "/opt/aws/bin/cfn-init -v ", " --stack ", Ref("AWS::StackName"), " --resource MainInstance ", " --configsets All ", " --access-key ", Ref("HostKeys"), " --secret-key ", GetAtt("HostKeys", "SecretAccessKey"), " --region ", Ref("AWS::Region"), "\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", Ref("AWS::StackName"), " --resource MainInstance ", " --region ", Ref("AWS::Region"), "\n", " > /var/tmp/cfn-init.output || error_exit 'Failed to run cfn-init'\n", "# All is well so signal success\n", "/opt/aws/bin/cfn-signal -e 0 -r \"Main Instance Stack setup complete\" '", Ref("WaitHandle"), "'\n" ])), # Expedited Json Obj # "UserData": { # "Fn::Base64": { # "Fn::Join": [ # "", # [ # "#!/bin/bash -v\n", # "yum update -y aws-cfn-bootstrap\n", # "# Install the files and packages from the metadata\n", # "\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", # "\n", # "# Install local config\n", # "/opt/aws/bin/cfn-init -v ", # " --stack ", # { # "Ref": "AWS::StackName" # }, # " --resource MainInstance ", # " --configsets All ", # " --access-key ", # { # "Ref": "HostKeys" # }, # " --secret-key ", # { # "Fn::GetAtt": [ # "HostKeys", # "SecretAccessKey" # ] # }, # " --region ", # { # "Ref": "AWS::Region" # }, # "\n", # "# Signal the status from cfn-init\n", # "/opt/aws/bin/cfn-signal -e $? ", # " --stack ", # { # "Ref": "AWS::StackName" # }, # " --resource MainInstance ", # " --region ", # { # "Ref": "AWS::Region" # }, # "\n", # " > /var/tmp/cfn-init.output || error_exit 'Failed to run cfn-init'\n", # "# All is well so signal success\n", # "/opt/aws/bin/cfn-signal -e 0 -r \"Main Instance Stack setup complete\" '", # { # "Ref": "WaitHandle" # }, # "'\n" # ] # ] # } # } # }, Tags=Tags(Name=Join(" - ", [ FindInMap("Environments", Ref("EnvironmentType"), "ValueTags"), "Perforce Helix App Server", Ref("AWS::StackName") ]), ), ImageId=FindInMap( "AWSRegionArch2AMI", Ref("AWS::Region"), FindInMap("AWSInstanceType2Arch", Ref("InstanceType"), "Arch")), KeyName=Ref("KeyName"), InstanceType=Ref("InstanceType"), NetworkInterfaces=[ NetworkInterfaceProperty( DeviceIndex="0", GroupSet=[Ref("VPCGroup")], DeleteOnTermination="true", AssociatePublicIpAddress="true", SubnetId=Ref("PublicSubnet"), PrivateIpAddress="10.0.0.51", ), ], DependsOn=["MainInstance"], ))
def _add_push_messages_api(self): self.MessagesServerRole = self.add_resource( Role( "MessagesServerRole", AssumeRolePolicyDocument=Policy( Version="2012-10-17", Statement=[ Statement(Effect=Allow, Action=[AssumeRole], Principal=Principal("Service", "ec2.amazonaws.com")) ]), Path="/", )) self.MessagesServerPolicy = self.add_resource( PolicyType("MessagesServerPolicy", PolicyName="MessagesServerRole", PolicyDocument=Policy( Version="2012-10-17", Statement=self.PushMessageStatements, ), Roles=[Ref(self.MessagesServerRole)], DependsOn="MessagesServerRole")) self.MessagesServerInstanceProfile = self.add_resource( InstanceProfile("MessagesServerInstanceProfile", Path="/", Roles=[Ref(self.MessagesServerRole)])) self.MessagesServerSG = self.add_resource( SecurityGroup( "MessagesServerSG", SecurityGroupIngress=[ allow_tcp(22), allow_tcp(80), ], VpcId=Ref(self.ProcessorVPCId), GroupDescription="Allow HTTP traffic to Message Server node", )) self.MessagesServerInstance = self.add_resource( Instance( "MessagesServerInstance", ImageId="ami-2c393546", InstanceType="t2.micro", SecurityGroupIds=[ GetAtt(self.LambdaProcessorSG, "GroupId"), GetAtt(self.MessagesServerSG, "GroupId"), ], KeyName=Ref(self.KeyPair), IamInstanceProfile=Ref(self.MessagesServerInstanceProfile), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT15M')), UserData=Base64( Join("", [ "#cloud-config\n\n", "coreos:\n", " units:\n", ] + self._aws_cfn_signal_service( "pushmessages", "MessagesServerInstance" ) + [ " - name: 'pushmessages.service'\n", " command: 'start'\n", " content: |\n", " [Unit]\n", " Description=Push Messages container\n", " Author=Mozilla Services\n", " After=docker.service\n", " \n", " [Service]\n", " Restart=always\n", " ExecStartPre=-/usr/bin/docker kill pushmessages\n", " ExecStartPre=-/usr/bin/docker rm pushmessages\n", " ExecStartPre=/usr/bin/docker pull ", "bbangert/push-messages:", Ref(self.PushMessagesVersion), "\n", " ExecStart=/usr/bin/docker run ", "--name pushmessages ", "-p 80:8000 ", "-e 'AWS_DEFAULT_REGION=us-east-1' ", "-e 'REDIS_ELASTICACHE=", Ref(self.RedisCluster), "' ", "bbangert/push-messages:", Ref(self.PushMessagesVersion), "\n", ])), SubnetId=Ref(self.MessageAPISubnetId), DependsOn="MessagesServerPolicy", Tags=self._instance_tags("push-messages", "push-messages"), )) self._template.add_output([ Output("MessagesAPI", Description="Push Messages API URL", Value=Join("", [ "http://", GetAtt(self.MessagesServerInstance, "PublicIp"), "/" ])) ])
"NATSecurityGroup", VpcId=Ref(VPC), GroupDescription="Controls traffic to our NAT instances", SecurityGroupIngress=nat_in_rules, )) nat_instances = [] for idx, public_subnet in enumerate(public_subnets): nat_instances.append( t.add_resource( Instance( 'NatInstance%d' % (idx, ), KeyName=Ref(keyname_param), ImageId=FindInMap('RegionMap', Ref('AWS::Region'), 'NATAMI'), SecurityGroupIds=[Ref(nat_sg)], SubnetId=Ref(public_subnet), InstanceType='t2.small', SourceDestCheck=False, Tags=[Tag('Name', 'NatGateway%d' % (idx, ))], DependsOn='AttachGateway', ))) add_autorecovery_to_instance(t, nat_instances[-1]) nat_eip = t.add_resource( EIP('NATEIP%d' % (idx, ), DependsOn='AttachGateway', Domain='vpc', InstanceId=Ref(nat_instances[-1]))) private_subnets = [] private_route_tables = [] for idx, private_cidr in enumerate(private_cidrs):
def test_goodrequired(self): Instance('ec2instance', ImageId="ami-xxxx", InstanceType="m1.small")
def test_required_title_error(self): with self.assertRaisesRegexp(ValueError, "title:"): t = Template() t.add_resource(Instance('ec2instance')) t.to_json()
netkan_instance = Instance( 'NetKANCompute', # ECS Optimised us-west-2 ImageId='ami-064803387adcb64b3', InstanceType='t3.small', IamInstanceProfile=Ref(netkan_profile), KeyName='techman83_alucard', SecurityGroups=['ckan-bot'], UserData=Base64(netkan_userdata), # t3 instances are unlimited by default CreditSpecification=CreditSpecification(CPUCredits='standard'), Tags=[ Tag(Key='Name', Value='NetKAN Indexer'), Tag(Key='Service', Value='Indexer'), ], Metadata=Metadata( Init({ 'config': InitConfig( files=InitFiles({ '/etc/cfn/cfn-hup.conf': cfn_hup, '/etc/cfn/hooks.d/cfn-auto-reloader.conf': reloader, '/etc/docker/daemon.json': docker, })), 'services': { 'sysvinit': { 'cfn': cfn_service, 'docker': docker_service, } }, })), BlockDeviceMappings=[ BlockDeviceMapping(DeviceName='/dev/xvdh', Ebs=EBSBlockDevice( VolumeSize='50', VolumeType='standard', )) ])
def test_badrequired(self): with self.assertRaises(ValueError): t = Template() t.add_resource(Instance('ec2instance')) t.to_json()
ToPort='22', CidrIp='10.10.0.0/32'), SecurityGroupRule(IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0') ], VpcId=Ref(vpc))) instance = t.add_resource( Instance('TestEC2Instance', ImageId='ami-0bea7fd38fabe821a', InstanceType='t2.micro', NetworkInterfaces=[ NetworkInterfaceProperty( GroupSet=[Ref(instanceSecurityGroup)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(subnet)) ])) dbUser = t.add_parameter( Parameter("DBUser", Type='String', MinLength='1', MaxLength='16', AllowedPattern='[a-zA-Z][a-zA-Z0-9]*')) dbPassword = t.add_parameter( Parameter("DBPassword",
def buildTemplate(self): self.vpc = self.template.add_resource( Stack('Vpc', TemplateURL= "https://s3.amazonaws.com/msel-cf-templates/vpc.template", Parameters={'Department': 'LAG'})) self.subnet = self.template.add_resource( Stack('Subnet', TemplateURL= 'https://s3.amazonaws.com/msel-cf-templates/subnet.template', Parameters={ 'VPCID': GetAtt(self.vpc, 'Outputs.VpcId'), 'CidrBlock': '10.0.1.0/24', 'Department': 'LAG', 'MapPublicIP': 'True', 'RouteTableId': GetAtt(self.vpc, 'Outputs.RouteTableId'), })) securitygroup = self.template.add_resource( SecurityGroup( "SecurityGroup", GroupDescription='SFX ports SSH, HTTP, HTTPS', VpcId=GetAtt(self.vpc, 'Outputs.VpcId'), SecurityGroupIngress=[ SecurityGroupRule( CidrIp='0.0.0.0/0', Description='Allow SSH (port 22) from all', FromPort='22', ToPort='22', IpProtocol='tcp', ), SecurityGroupRule( CidrIp='0.0.0.0/0', Description='Allow HTTP (port 80) from all', FromPort='80', ToPort='80', IpProtocol='tcp', ), SecurityGroupRule( CidrIp='0.0.0.0/0', Description='Allow HTTPS (port 443) from all', FromPort='443', ToPort='443', IpProtocol='tcp', ), ])) self.eip = self.template.add_resource(EIP('EIP')) self.instance = self.template.add_resource( Instance( 'SFXInstance', ImageId=Ref(self.paramImageId), KeyName=Ref(self.paramKeyName), SubnetId=GetAtt(self.subnet, 'Outputs.SubnetId'), SecurityGroupIds=[Ref(securitygroup)], Tags=Tags( Name='SFX Test Instance', Department='LAG', Project='SFX', ), UserData=Base64(Ref(self.userdata)), )) self.template.add_resource( EIPAssociation( "EIPAssoc", EIP=Ref(self.eip), InstanceId=Ref(self.instance), )) self.template.add_resource( RecordSetType( "dnsRecord", HostedZoneName=Join("", ['cloud.library.jhu.edu', '.']), Comment="SFX-Test", Name=Join('', ['sfx-test', ".", "cloud.library.jhu.edu"]), Type="A", TTL="300", ResourceRecords=[GetAtt(self.instance, 'PublicIp')], ))
# - 2 in the private subnet privInst01 = t.add_resource( Instance( 'cpPrivInstance01', ImageId=ImageID, InstanceType='t2.micro', Tags=[{ "Key": "Name", "Value": "cp_priv_instance_1" }], KeyName=Ref(ssh_keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty(GroupSet=[Ref(backendSecurityGroup)], DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(privateSubnet)) ], UserData=Base64( Join('', [ '#!/bin/bash -v\n', "sudo yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E '%{rhel}').noarch.rpm &>/root/user-data.log\n", 'sudo yum install -y python-pip &>>/root/user-data.log\n', 'sudo pip install Flask &>>/root/user-data.log\n', 'sudo yum install -y git &>>/root/user-data.log\n', 'sudo mkdir -p /root/work && cd /root/work/ && git clone -v https://github.com/cjurju/pikachuFly.git . &>>/root/user-data.log\n', 'sudo python /root/work/python-troposphere/HelloWorld.py & &>>/root/user-data.log' ])))) pubInst01 = t.add_resource( Instance(
mongo_instance = Instance( mongo_instance_name, template=template, KeyName=Ref(secret_key), NetworkInterfaces=[ NetworkInterfaceProperty( AssociatePublicIpAddress=True, SubnetId=Ref(public_subnet), DeviceIndex="0", GroupSet=[Ref(instance_security_group)], ) ], ImageId=FindInMap("InstanceRegionMap", Ref(AWS_REGION), "AMI"), # SecurityGroupIds=[Ref(default_security_group)], InstanceType=instance_type, UserData=Base64( Join('', [ "#!/bin/bash -xe\n", "sleep 30s\n", "touch /tmp/init.log\n", "yum update -y\n", "echo update-done >> /tmp/init.log\n", "yum install -y docker \n", "echo docker-install-done >> /tmp/init.log\n", "usermod -a -G docker ec2-user \n", "service docker start\n", "echo docker-start-done >> /tmp/init.log\n", "mkdir -p /data\n", "docker run --name mongo -v /data:/data/db -p 27017:27017 -d mongo --auth\n", "echo docker-mongo-started >> /tmp/init.log\n", "sleep 5s \n", "docker exec mongo mongo admin --eval \"db.createUser({ user: '******', pwd: '", mongo_pass, "', roles: [ { role: 'userAdminAnyDatabase', db: 'admin' }, { role: 'dbAdminAnyDatabase', db: 'admin' }, { role: 'readWriteAnyDatabase', db: 'admin' } ] });\"\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", Ref('AWS::StackName'), " --resource %s " % mongo_instance_name, ' --region ', Ref('AWS::Region'), '\n', "docker restart mongo", "echo docker-mongo-restarted >> /tmp/init.log\n" ])), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT15M')), Tags=Tags(Name="mongo_db_instance"))
def __init__(self): self.name = 'ec2.template' self.template = Template() self.template.add_version("2010-09-09") self.test_parameter_groups = TestParameterGroups() default_test_params = TestParameterGroup() self.test_parameter_groups.add(default_test_params) Environment = self.template.add_parameter(Parameter( "Environment", Default="Development", Type="String", Description="Application environment", AllowedValues=["Development", "Integration", "PreProduction", "Production", "Staging", "Test"], )) default_test_params.add(TestParameter("Environment", "Integration")) Bucket = self.template.add_parameter(Parameter( "S3Bucket", Type="String", Description="S3 Bucket", )) default_test_params.add(TestParameter("S3Bucket", "Arn", S3Bucket())) ImageId = self.template.add_parameter(Parameter( "ImageId", Type="String", Description="Image Id" )) default_test_params.add(TestParameter("ImageId", "ami-6869aa05")) self.template.add_resource(Instance( "EC2Instance", Tags=Tags( Name=Ref("AWS::StackName"), ServiceProvider="Rackspace", Environment=Ref(Environment), ), InstanceType="t2.small", ImageId=Ref(ImageId), )) EC2Policy = Policy( PolicyName="EC2_S3_Access", PolicyDocument={ "Statement": [{ "Effect": "Allow", "Action": "s3:*", "Resource": Ref(Bucket) }] }) EC2InstanceRole = self.template.add_resource(Role( "EC2InstanceRole", AssumeRolePolicyDocument={ "Statement": [{ "Effect": "Allow", "Principal": { "Service": ["ec2.amazonaws.com"] }, "Action": ["sts:AssumeRole"] }] }, Path="/", Policies=[EC2Policy], )) self.template.add_resource(InstanceProfile( "EC2InstanceProfile", Path="/", Roles=[Ref(EC2InstanceRole)] ))
# FIXME: --associate-public-ip-address # FIXME: aws ec2 allocate-address ec2Instance = t.add_resource( Instance( "Ec2Instance", DependsOn='InternetGatewayAttachment', BlockDeviceMappings=[ BlockDeviceMapping(DeviceName="/dev/sda1", Ebs=EBSBlockDevice( VolumeSize="128", VolumeType="gp2", )), ], ImageId=Ref(imageId_param), InstanceType=Ref(instanceType_param), KeyName=Ref(keyname_param), # NetworkInterfaces=[ # NetworkInterfaceProperty( # GroupSet=[Ref(ec2SecurityGroup)], # AssociatePublicIpAddress=True, # DeviceIndex=0, # DeleteOnTermination=True, # SubnetId=Ref(publicSubnet), # ) # ] SecurityGroupIds=[Ref(ec2SecurityGroup)], SubnetId=Ref(publicSubnet), # UserData=Base64("80") )) # eip = t.add_resource( # EIP(
"NatSecurityGroup", SecurityGroupIngress=[ { "ToPort": "22", "IpProtocol": "tcp", "CidrIp": "0.0.0.0/0", "FromPort": "22" }, { "ToPort": "65535", "IpProtocol": "-1", "CidrIp": "10.0.0.0/16", "FromPort": "0" } ], VpcId=Ref(AlchemyVPC), SecurityGroupEgress=[{ "ToPort": "65535", "IpProtocol": "-1", "CidrIp": "0.0.0.0/0", "FromPort": "0" }], GroupDescription="Enable all communication on private subnet", )) natProxyEC2Instance = t.add_resource(Instance( "natProxyEC2Instance", UserData=Base64(Join("", ["#!/bin/bash\n", "yum update -y && yum install -y yum-cron && chkconfig yum-cron on"])), SourceDestCheck="false", InstanceType="t2.small", ImageId=FindInMap("NatRegionMap", Ref("AWS::Region"), "AMI"), KeyName=Ref(SecurityKeyName), SubnetId=Ref(publicASubnet), SecurityGroupIds=[Ref(NatSecurityGroup)], Tags=Tags(Name=Join("",[Ref(ClusterName), " NAT Instance"])) )) NATIPAddress = t.add_resource(EIP("NATIPAddress", Domain='vpc')) NATEIPAttachment = t.add_resource(EIPAssociation( "NATEIPAttachment", InstanceId=Ref(natProxyEC2Instance), AllocationId= GetAtt(NATIPAddress, "AllocationId") )) ### END OF NAT/SSH TUNNEL SETUP ###
def generate_template(service_name): t = Template() t.add_version('2010-09-09') t.add_description("""\ AWS CloudFormation Template for AWS Exploitation Lab """) t.add_mapping("PublicRegionMap", ami_public_mapping) t.add_mapping("PrivateRegionMap", ami_private_mapping) keyname_param = t.add_parameter( Parameter( 'KeyName', ConstraintDescription='must be the name of an existing EC2 KeyPair.', Description='Name of an existing EC2 KeyPair to enable SSH access to \ the instance', Type='AWS::EC2::KeyPair::KeyName', )) sshlocation_param = t.add_parameter( Parameter( 'SSHLocation', Description=' The IP address range that can be used to SSH to the EC2 \ instances', Type='String', MinLength='9', MaxLength='18', Default='0.0.0.0/0', AllowedPattern="(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})", ConstraintDescription=( "must be a valid IP CIDR range of the form x.x.x.x/x."), )) instanceType_param = t.add_parameter(Parameter( 'InstanceType', Type='String', Description='WebServer EC2 instance type', Default='t2.micro', AllowedValues=[ 't2.micro', 't2.small', 't2.medium', 'm3.medium', 'm3.large', 'm3.xlarge', 'm3.2xlarge', ], ConstraintDescription='must be a valid EC2 instance type.', )) ref_stack_id = Ref('AWS::StackId') ec2_role = t.add_resource(Role( "%sEC2Role" % service_name, AssumeRolePolicyDocument=awacs.aws.Policy( Statement=[ awacs.aws.Statement( Effect=awacs.aws.Allow, Action=[awacs.aws.Action("sts", "AssumeRole")], Principal=awacs.aws.Principal("Service", ["ec2.amazonaws.com"]) ) ] ) )) ec2_role.ManagedPolicyArns = [ "arn:aws:iam::aws:policy/ReadOnlyAccess" ] ec2_snapshot_policy_document = awacs.aws.Policy( Statement=[ awacs.aws.Statement( Sid="PermitEC2Snapshots", Effect=awacs.aws.Allow, Action=[ awacs.aws.Action("ec2", "CreateSnapshot"), awacs.aws.Action("ec2", "ModifySnapshotAttribute"), ], Resource=["*"] ) ] ) ec2_snapshot_policy = Policy( PolicyName="EC2SnapshotPermissions", PolicyDocument=ec2_snapshot_policy_document ) priv_ec2_role = t.add_resource(Role( "%sPrivEC2Role" % service_name, AssumeRolePolicyDocument=awacs.aws.Policy( Statement=[ awacs.aws.Statement( Effect=awacs.aws.Allow, Action=[awacs.aws.Action("sts", "AssumeRole")], Principal=awacs.aws.Principal("Service", ["ec2.amazonaws.com"]) ) ] ), Policies=[ec2_snapshot_policy] )) priv_ec2_role.ManagedPolicyArns = [ "arn:aws:iam::aws:policy/ReadOnlyAccess" ] VPC_ref = t.add_resource( VPC( 'VPC', CidrBlock='10.0.0.0/16', Tags=Tags( Application=ref_stack_id))) instanceProfile = t.add_resource( InstanceProfile( "InstanceProfile", InstanceProfileName="%sInstanceRole" % (service_name), Roles=[Ref(ec2_role)])) privInstanceProfile = t.add_resource( InstanceProfile( "PrivInstanceProfile", InstanceProfileName="%sPrivInstanceRole" % (service_name), Roles=[Ref(priv_ec2_role)])) public_subnet = t.add_resource( Subnet( '%sSubnetPublic' % service_name, MapPublicIpOnLaunch=True, CidrBlock='10.0.1.0/24', VpcId=Ref(VPC_ref), Tags=Tags( Application=ref_stack_id, Name="%sSubnet_public" % (service_name)) ) ) private_subnet = t.add_resource( Subnet( '%sSubnetPrivate' % service_name, MapPublicIpOnLaunch=False, CidrBlock='10.0.2.0/24', VpcId=Ref(VPC_ref), Tags=Tags( Application=ref_stack_id, Name="%sSubnet_private" % (service_name)) ) ) internetGateway = t.add_resource( InternetGateway( 'InternetGateway', Tags=Tags( Application=ref_stack_id, Name="%sInternetGateway" % service_name))) gatewayAttachment = t.add_resource( VPCGatewayAttachment( 'AttachGateway', VpcId=Ref(VPC_ref), InternetGatewayId=Ref(internetGateway))) routeTable = t.add_resource( RouteTable( 'RouteTable', VpcId=Ref(VPC_ref), Tags=Tags( Application=ref_stack_id, Name="%sRouteTable" % service_name))) route = t.add_resource( Route( 'Route', DependsOn='AttachGateway', GatewayId=Ref('InternetGateway'), DestinationCidrBlock='0.0.0.0/0', RouteTableId=Ref(routeTable), )) # Only associate this Route Table with the public subnet subnetRouteTableAssociation = t.add_resource( SubnetRouteTableAssociation( 'SubnetRouteTableAssociation', SubnetId=Ref(public_subnet), RouteTableId=Ref(routeTable), )) instanceSecurityGroup = t.add_resource( SecurityGroup( 'InstanceSecurityGroup', GroupDescription='%sSecurityGroup' % service_name, SecurityGroupIngress=[ SecurityGroupRule( IpProtocol='tcp', FromPort='22', ToPort='22', CidrIp=Ref(sshlocation_param)), SecurityGroupRule( IpProtocol='tcp', FromPort='80', ToPort='80', CidrIp='0.0.0.0/0'), SecurityGroupRule( IpProtocol='tcp', FromPort='1080', ToPort='1080', CidrIp='0.0.0.0/0'), SecurityGroupRule( IpProtocol='tcp', FromPort='443', ToPort='443', CidrIp='0.0.0.0/0'), SecurityGroupRule( IpProtocol='tcp', FromPort='0', ToPort='65535', CidrIp="10.0.0.0/8"), ], VpcId=Ref(VPC_ref), ) ) public_instance = t.add_resource( Instance( "Public%sInstance" % service_name, ImageId=FindInMap("PublicRegionMap", Ref("AWS::Region"), "AMI"), InstanceType=Ref(instanceType_param), KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty( GroupSet=[ Ref(instanceSecurityGroup)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(public_subnet))], UserData=Base64(public_instance_userdata), Tags=Tags( Application=ref_stack_id, Name='%sPublicInstance' % (service_name)) ) ) private_instance = t.add_resource( Instance( "Private%sInstance" % service_name, ImageId=FindInMap("PrivateRegionMap", Ref("AWS::Region"), "AMI"), InstanceType=Ref(instanceType_param), KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty( GroupSet=[ Ref(instanceSecurityGroup)], DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(private_subnet))], UserData=Base64(private_instance_userdata), Tags=Tags( Application=ref_stack_id, Name='%sPrivateInstance' % (service_name)), IamInstanceProfile="%sPrivInstanceRole" % (service_name) ) ) outputs = [] outputs.append( Output( "PublicIP", Description="IP Address of Public Instance", Value=GetAtt(public_instance, "PublicIp"), ) ) t.add_output(outputs) # Set up S3 Bucket and CloudTrail S3Bucket = t.add_resource( Bucket( "S3Bucket", DeletionPolicy="Retain" ) ) S3PolicyDocument=awacs.aws.PolicyDocument( Id='EnforceServersideEncryption', Version='2012-10-17', Statement=[ awacs.aws.Statement( Sid='PermitCTBucketPut', Action=[s3.PutObject], Effect=awacs.aws.Allow, Principal=awacs.aws.Principal("Service", ["cloudtrail.amazonaws.com"]), Resource=[Join('', [s3.ARN(''), Ref(S3Bucket), "/*"])], ), awacs.aws.Statement( Sid='PermitCTBucketACLRead', Action=[s3.GetBucketAcl], Effect=awacs.aws.Allow, Principal=awacs.aws.Principal("Service", ["cloudtrail.amazonaws.com"]), Resource=[Join('', [s3.ARN(''), Ref(S3Bucket)])], ) ] ) S3BucketPolicy = t.add_resource( BucketPolicy( "BucketPolicy", PolicyDocument=S3PolicyDocument, Bucket=Ref(S3Bucket), DependsOn=[S3Bucket] ) ) myTrail = t.add_resource( Trail( "CloudTrail", IsLogging=True, S3BucketName=Ref(S3Bucket), DependsOn=["BucketPolicy"], ) ) myTrail.IsMultiRegionTrail = True myTrail.IncludeGlobalServiceEvents = True return t.to_json()
def test_running_script_on_startup_using_user_data(self): test_stack_name = 'TestRunningUserData' init_cf_env(test_stack_name) ### now = str(datetime.datetime.now()) t = Template() security_group = t.add_resource( SecurityGroup("SecurityGroup", GroupDescription="Enable all ingress", VpcId=get_default_vpc(), SecurityGroupIngress=[ SecurityGroupRule(IpProtocol='tcp', CidrIp="0.0.0.0/0", FromPort=0, ToPort=65535), ], Tags=Tags( Application=Ref("AWS::StackName"), Developer="cisco::haoru", ))) instance = t.add_resource( Instance( "MyInstance", KeyName=KEY, InstanceType="m4.xlarge", ImageId=get_linux2_image_id( ), # linux2 has /opt/aws/bin/cfn-signal preinstalled NetworkInterfaces=[ NetworkInterfaceProperty(AssociatePublicIpAddress=True, DeviceIndex=0, GroupSet=[Ref(security_group)], SubnetId=get_first_subnet()), ], UserData=Base64( Join( '', [ '#!/bin/bash -xe\n', # user data that begins with shebang will be executed f'echo "{now}" > /tmp/now\n', '/opt/aws/bin/cfn-signal -e $? ', # send signal to let cloud formation know it is ready ' --stack ', Ref("AWS::StackName"), ' --resource MyInstance ', ' --region ', Ref("AWS::Region"), '\n' ])), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT10M') # expect to receive signal in 10 mins ), Tags=Tags( Name="aws test user data", Application=Ref("AWS::StackName"), Developer="cisco::haoru", ), )) t.add_output([ Output( "InstanceId", Description="InstanceId of the newly created EC2 instance", Value=Ref(instance), ), Output( "PublicIP", Description= "Public IP address of the newly created EC2 instance", Value=GetAtt(instance, "PublicIp"), ), ]) dump_template(t, True) cf_client.create_stack(StackName=test_stack_name, TemplateBody=t.to_yaml()) cf_client.get_waiter('stack_create_complete').wait( StackName=test_stack_name) public_ip = key_find( cf_client.describe_stacks( StackName=test_stack_name)['Stacks'][0]['Outputs'], 'OutputKey', 'PublicIP')['OutputValue'] actual = run( f"ssh -o 'StrictHostKeyChecking no' ec2-user@{public_ip} cat /tmp/now" ) self.assertEqual(actual, now)
hugged_instance = t.add_resource(Instance( "HuggedInstance", Metadata=Init({ "config": InitConfig( files=InitFiles({ '/etc/cfn/cfn-hup.conf': cfn_hup, '/etc/cfn/hooks.d/cfn-auto-reloader.conf': reloader, '/etc/docker/daemon.json': docker, }), ), 'services': { 'sysvinit': { 'cfn': cfn_service, 'docker': docker_service, } } }), ImageId='ami-0adc350d7c7a2259f', KeyName='Seras', Tags=Tags( Name=Join("", [Ref("AWS::StackName")]), Application=Ref("AWS::StackId"), ), InstanceType='t3.nano', IamInstanceProfile=Ref(hugged_profile), SecurityGroupIds=[SECURITY_GROUP], CreditSpecification=CreditSpecification(CPUCredits='standard'), UserData=Base64(Join( "", [ "#!/bin/bash -xe\n", "echo ECS_CLUSTER=AllTheHugs > /etc/ecs/ecs.config\n", "yum install -y aws-cfn-bootstrap\n", "# Install the files and packages from the metadata\n", "/opt/aws/bin/cfn-init -v ", " --stack ", Ref("AWS::StackName"), " --resource HuggedInstance ", " --region ", Ref("AWS::Region"), "\n", "# Get our certificates\n", "docker run -v /opt/letsencrypt:/etc/letsencrypt/ certbot/dns-route53 certonly -n --agree-tos --email ", EMAIL, " --dns-route53 -d ", FQDN, "\n", "(cd /opt && mkdir certs && cp -L letsencrypt/live/", FQDN, "/*.pem certs/.)\n", "# Should do something better than this\n", "chmod 0644 /opt/certs/privkey.pem\n", "# Start up the cfn-hup daemon to listen for changes to the metadata\n", "/opt/aws/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n", "# Signal the status from cfn-init\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", Ref("AWS::StackName"), " --resource HuggedInstance ", " --region ", Ref("AWS::Region"), "\n" ] )), ))
def test_creating_all_in_one(self): ''' Create VPC, Subnets, IGW, Route, SecurityGroup, Instance at once. ''' test_stack_name = 'TestStack' cf_client.delete_stack(StackName=test_stack_name) cf_client.get_waiter('stack_delete_complete').wait( StackName=test_stack_name) ### t = Template() keyname_param = t.add_parameter( Parameter( "KeyName", Description= "Name of an existing EC2 KeyPair to enable SSH access to the instance", Type="String", )) t.add_mapping( 'RegionMap', { "us-east-1": { "AMI": "ami-7f418316" }, "us-east-2": { "AMI": "ami-0c55b159cbfafe1f0" }, "us-west-1": { "AMI": "ami-951945d0" }, "us-west-2": { "AMI": "ami-16fd7026" }, "eu-west-1": { "AMI": "ami-24506250" }, "sa-east-1": { "AMI": "ami-3e3be423" }, "ap-southeast-1": { "AMI": "ami-74dda626" }, "ap-northeast-1": { "AMI": "ami-dcfa4edd" } }) t.add_resource( VPC("VPC", EnableDnsSupport="true", CidrBlock="10.100.0.0/16", EnableDnsHostnames="true", Tags=Tags( Application=Ref("AWS::StackName"), Developer="cisco::haoru", ))) t.add_resource( InternetGateway("InternetGateway", Tags=Tags( Application=Ref("AWS::StackName"), Developer="cisco::haoru", ))) t.add_resource( VPCGatewayAttachment( "IGWAttachment", VpcId=Ref("VPC"), InternetGatewayId=Ref("InternetGateway"), )) t.add_resource( RouteTable("RouteTable", VpcId=Ref("VPC"), Tags=Tags( Application=Ref("AWS::StackName"), Developer="cisco::haoru", ))) t.add_resource( Route( "IGWRoute", DependsOn='IGWAttachment', GatewayId=Ref("InternetGateway"), DestinationCidrBlock="0.0.0.0/0", RouteTableId=Ref("RouteTable"), )) # loop through usable availability zones for the aws account and create a subnet for each zone for i, az in list(enumerate(get_azs(), start=1)): t.add_resource( Subnet("PublicSubnet{0}".format(i), VpcId=Ref("VPC"), CidrBlock="10.100.{0}.0/24".format(i), AvailabilityZone="{0}".format(az), MapPublicIpOnLaunch=True, Tags=Tags( Application=Ref("AWS::StackName"), Developer="cisco::haoru", ))) # have to do this, or else subnet will use vpc default router table, # which only has one entry of default local route. t.add_resource( SubnetRouteTableAssociation( "SubnetRouteTableAssociation{0}".format(i), SubnetId=Ref("PublicSubnet{0}".format(i)), RouteTableId=Ref("RouteTable"), )) t.add_resource( SecurityGroup("SecurityGroup", GroupDescription="Enable all ingress", VpcId=Ref('VPC'), SecurityGroupIngress=[ SecurityGroupRule(IpProtocol='tcp', CidrIp="0.0.0.0/0", FromPort=0, ToPort=65535), ], Tags=Tags( Application=Ref("AWS::StackName"), Developer="cisco::haoru", ))) ec2_instance = t.add_resource( Instance( "Instance", SecurityGroupIds=[Ref('SecurityGroup')], SubnetId=Ref('PublicSubnet1'), KeyName=Ref(keyname_param), InstanceType="m4.xlarge", ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"), Tags=Tags( Name="aws test troposphere", Application=Ref("AWS::StackName"), Developer="cisco::haoru", ), )) t.add_output([ Output( "InstanceId", Description="InstanceId of the newly created EC2 instance", Value=Ref(ec2_instance), ), Output( "AZ", Description= "Availability Zone of the newly created EC2 instance", Value=GetAtt(ec2_instance, "AvailabilityZone"), ), Output( "PublicIP", Description= "Public IP address of the newly created EC2 instance", Value=GetAtt(ec2_instance, "PublicIp"), ), Output( "PrivateIP", Description= "Private IP address of the newly created EC2 instance", Value=GetAtt(ec2_instance, "PrivateIp"), ), Output( "PublicDNS", Description="Public DNSName of the newly created EC2 instance", Value=GetAtt(ec2_instance, "PublicDnsName"), ), Output( "PrivateDNS", Description="Private DNSName of the newly created EC2 instance", Value=GetAtt(ec2_instance, "PrivateDnsName"), ), ]) dump_template(t, True) cf_client.create_stack( StackName=test_stack_name, TemplateBody=t.to_yaml(), Parameters=[{ 'ParameterKey': 'KeyName', 'ParameterValue': KEY # Change this value as you wish }]) cf_client.get_waiter('stack_create_complete').wait( StackName=test_stack_name) public_ip = key_find( cf_client.describe_stacks( StackName=test_stack_name)['Stacks'][0]['Outputs'], 'OutputKey', 'PublicIP')['OutputValue'] time.sleep(5) run(f"ssh -o 'StrictHostKeyChecking no' ubuntu@{public_ip} curl -s ifconfig.me" ) # run ssh-add <KEY> beforehand
def test_badproperty(self): with self.assertRaises(AttributeError): Instance( 'ec2instance', foobar=True, )
}, "sa-east-1": { "AMI": "ami-3e3be423" }, "ap-southeast-1": { "AMI": "ami-74dda626" }, "ap-northeast-1": { "AMI": "ami-dcfa4edd" } }) instance = t.add_resource( Instance( "Ec2Instance", ImageId=FindInMap("RegionMap", Ref("AWS::Region"), "AMI"), InstanceType="m1.small", )) myDNSRecord = t.add_resource( RecordSetType( "myDNSRecord", HostedZoneName=Join("", [Ref(hostedzone), "."]), Comment="DNS name for my instance.", Name=Join("", [ Ref(instance), ".", Ref("AWS::Region"), ".", Ref(hostedzone), "." ]), Type="A", TTL="900",
def test_badtype(self): with self.assertRaises(AttributeError): Instance('ec2instance', image_id=0.11)
"export install_ambari_server=", install_ambari_server ,"\n", ] return exports + bootstrap_script_body.splitlines(True) AmbariNode = t.add_resource(Instance( "AmbariNode", UserData=Base64(Join("", my_bootstrap_script('AmbariNode','true','true','127.0.0.1'))), ImageId=FindInMap("RHEL66", Ref("AWS::Region"), "AMI"), BlockDeviceMappings=[my_block_device_mappings_root("/dev/sd","100","gp2")], CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal( Count=1, Timeout="PT30M" )), KeyName=Ref(KeyName), IamInstanceProfile=Ref(AmbariInstanceProfile), InstanceType=Ref(AmbariInstanceType), NetworkInterfaces=[ NetworkInterfaceProperty( DeleteOnTermination="true", DeviceIndex="0", SubnetId=Ref(PublicSubnet), GroupSet=[Ref(AmbariSecurityGroup)], AssociatePublicIpAddress="true", ), ], )) WorkerNodeLaunchConfig = t.add_resource(LaunchConfiguration( "WorkerNodeLaunchConfig", UserData=Base64(Join("", my_bootstrap_script('WorkerNodes','true','false',ref_ambariserver))),
def test_ref(self): name = 'fake' t = Template() resource = t.add_resource(Instance(name)) self.assertEqual(resource.name, name)
Instance( 'WebServerInstance', Metadata=instance_metadata, ImageId=Ref(amiid_param), InstanceType=Ref(instanceType_param), KeyName=Ref(keyname_param), NetworkInterfaces=[ NetworkInterfaceProperty( GroupSet=[ Ref(instanceSecurityGroup)], AssociatePublicIpAddress='true', DeviceIndex='0', DeleteOnTermination='true', SubnetId=Ref(subnet))], UserData=Base64( Join( '', [ '#!/bin/bash -xe\n', 'yum update -y aws-cfn-bootstrap\n', '/opt/aws/bin/cfn-init -v ', ' --stack ', Ref('AWS::StackName'), ' --resource WebServerInstance ', ' --region ', Ref('AWS::Region'), '\n', '/opt/aws/bin/cfn-signal -e $? ', ' --stack ', Ref('AWS::StackName'), ' --resource WebServerInstance ', ' --region ', Ref('AWS::Region'), '\n', ])), CreationPolicy=CreationPolicy( ResourceSignal=ResourceSignal( Timeout='PT15M')), Tags=Tags( Application=ref_stack_id), ))
env_param = base_template.add_parameter( Parameter("Environment", Description="Please enter a work environment (Test,Dev,Prod)", AllowedValues=["test", "dev", "prod"], Type="String")) security_rules = SecurityGroupRule(IpProtocol='tcp', FromPort='22', ToPort='22') security_group = SecurityGroup( "Si3mShadySecG", GroupDescription="SecG made from python3 and troposphere", SecurityGroupIngress=[security_rules]) secG = base_template.add_resource(security_group) s3bucket = base_template.add_resource(Bucket("GoodBucketFromTroposphere")) ec2_image = base_template.add_resource( Instance("MadeWithTroposphere", ImageId=FindInMap("Environment", Ref(env_param), "AMI"), InstanceType=FindInMap("InstanceType", Ref(env_param), "type"), KeyName="keyZ", SecurityGroups=[Ref(security_group)])) print(base_template.to_yaml()) #Using troposphere to generate infrastructure as code with Cloudformation and good Documentation (Ec2, SecGroup, with Mapping and Parameters) #Elliott Arnold June 4, 2019 #https://github.com/cloudtools/troposphere
def _add_autopush_servers(self): self.PushServerInstanceProfile = self.add_resource( InstanceProfile("AutopushServerInstanceProfile", Path="/", Roles=[Ref(self.PushServerRole)])) # Extras is common options for UserData extras = [ "--hostname $public_ipv4 ", "--storage_tablename ", Ref(self.PushTablePrefix), "_storage ", "--message_tablename ", Ref(self.PushTablePrefix), "_message ", "--router_tablename ", Ref(self.PushTablePrefix), "_router ", "--crypto_key '", Ref(self.PushCryptoKey), "' ", ] if self.use_firehose: extras.extend( ["--firehose_stream_name ", Ref(self.FirehoseLogstream), " "]) self.PushEndpointServerInstance = self.add_resource( Instance( "AutopushEndpointInstance", ImageId="ami-2c393546", InstanceType="t2.micro", SecurityGroups=[ Ref(self.EndpointSG), Ref(self.InternalRouterSG), ], KeyName=Ref(self.KeyPair), IamInstanceProfile=Ref(self.PushServerInstanceProfile), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT15M')), UserData=Base64( Join("", [ "#cloud-config\n\n", "coreos:\n", " units:\n", ] + self._aws_cfn_signal_service( "autoendpoint", "AutopushEndpointInstance" ) + [ " - name: 'autoendpoint.service'\n", " command: 'start'\n", " content: |\n", " [Unit]\n", " Description=Autoendpoint container\n", " Author=Mozilla Services\n", " After=docker.service\n", " \n", " [Service]\n", " Restart=always\n", " ExecStartPre=-/usr/bin/docker kill autoendpoint\n", " ExecStartPre=-/usr/bin/docker rm autoendpoint\n", " ExecStartPre=/usr/bin/docker pull ", "bbangert/autopush:", Ref(self.AutopushVersion), "\n", " ExecStart=/usr/bin/docker run ", "--name autoendpoint ", "-p 8082:8082 ", "-e 'AWS_DEFAULT_REGION=us-east-1' ", "bbangert/autopush:", Ref(self.AutopushVersion), " ", "./pypy/bin/autoendpoint ", ] + extras)), DependsOn="AutopushServerRolePolicy", Tags=self._instance_tags("autopush", "autoendpoint"), )) self.PushConnectionServerInstance = self.add_resource( Instance( "AutopushConnectionInstance", ImageId="ami-2c393546", InstanceType="t2.micro", SecurityGroups=[ Ref(self.ConnectionSG), Ref(self.InternalRouterSG), ], KeyName=Ref(self.KeyPair), IamInstanceProfile=Ref(self.PushServerInstanceProfile), CreationPolicy=CreationPolicy(ResourceSignal=ResourceSignal( Timeout='PT15M')), UserData=Base64( Join("", [ "#cloud-config\n\n", "coreos:\n", " units:\n", ] + self._aws_cfn_signal_service( "autopush", "AutopushConnectionInstance" ) + [ " - name: 'autopush.service'\n", " command: 'start'\n", " content: |\n", " [Unit]\n", " Description=Autopush container\n", " Author=Mozilla Services\n", " After=docker.service\n", " \n", " [Service]\n", " Restart=always\n", " ExecStartPre=-/usr/bin/docker kill autopush\n", " ExecStartPre=-/usr/bin/docker rm autopush\n", " ExecStartPre=/usr/bin/docker pull ", "bbangert/autopush:", Ref(self.AutopushVersion), "\n", " ExecStart=/usr/bin/docker run ", "--name autopush ", "-p 8080:8080 ", "-p 8081:8081 ", "-e 'AWS_DEFAULT_REGION=us-east-1' ", "bbangert/autopush:", Ref(self.AutopushVersion), " ", "./pypy/bin/autopush ", "--router_hostname $private_ipv4 ", "--endpoint_hostname ", GetAtt(self.PushEndpointServerInstance, "PublicDnsName"), " ", ] + extras)), DependsOn="AutopushServerRolePolicy", Tags=self._instance_tags("autopush", "autopush"), )) self._template.add_output([ Output("PushServerURL", Description="Push Websocket URL", Value=Join("", [ "ws://", GetAtt(self.PushConnectionServerInstance, "PublicDnsName"), ":8080/" ])) ])