{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "AWS CloudFormation template that sets up CloudTrail, a secure S3 bucket, and a VPC appropriate for analyzing dbGaP data using Elastic MapReduce", "Mappings" : { "SubnetConfig" : { "VPC" : { "CIDR" : "10.0.0.0/24" }, "Public" : { "CIDR" : "10.0.0.0/24" } } }, "Parameters" : { "SecureBucket": { "Description": "Name of secure bucket to which Rail's intermediate data and output as well as CloudTrail's output are written.", "Type": "String" } }, "Resources" : { "S3Bucket": { "DeletionPolicy" : "Retain", "Type" : "AWS::S3::Bucket", "Properties": { "BucketName" : {"Ref" : "SecureBucket"} } }, "BucketPolicy" : { "Type" : "AWS::S3::BucketPolicy", "Properties" : { "Bucket" : {"Ref" : "S3Bucket"}, "PolicyDocument" : { "Version": "2012-10-17", "Statement": [ { "Sid": "AWSCloudTrailAclCheck", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::903692715234:root", "arn:aws:iam::859597730677:root", "arn:aws:iam::814480443879:root", "arn:aws:iam::216624486486:root", "arn:aws:iam::086441151436:root", "arn:aws:iam::388731089494:root", "arn:aws:iam::284668455005:root", "arn:aws:iam::113285607260:root" ] }, "Action": "s3:GetBucketAcl", "Resource": { "Fn::Join" : ["", ["arn:aws:s3:::", {"Ref":"S3Bucket"}]]} }, { "Sid": "AWSCloudTrailWrite", "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::903692715234:root", "arn:aws:iam::859597730677:root", "arn:aws:iam::814480443879:root", "arn:aws:iam::216624486486:root", "arn:aws:iam::086441151436:root", "arn:aws:iam::388731089494:root", "arn:aws:iam::284668455005:root", "arn:aws:iam::113285607260:root" ] }, "Action": "s3:PutObject", "Resource": { "Fn::Join" : ["", ["arn:aws:s3:::", {"Ref":"S3Bucket"}, "/AWSLogs/", {"Ref":"AWS::AccountId"}, "/*"]]}, "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } } }, { "Sid":"DenyUnEncryptedObjectUploads", "Effect":"Deny", "Principal":"*", "Action":"s3:PutObject", "Resource":{ "Fn::Join" : ["", ["arn:aws:s3:::", {"Ref":"S3Bucket"}, "/*"]]}, "Condition":{ "StringNotEquals":{ "s3:x-amz-server-side-encryption":"AES256" } } } ] } } }, "secureTrail" : { "DependsOn" : ["BucketPolicy"], "Type" : "AWS::CloudTrail::Trail", "Properties" : { "S3BucketName" : {"Ref":"S3Bucket"}, "IsLogging" : true } }, "VPC" : { "Type" : "AWS::EC2::VPC", "Properties" : { "EnableDnsSupport" : "true", "EnableDnsHostnames" : "true", "CidrBlock" : { "Fn::FindInMap" : [ "SubnetConfig", "VPC", "CIDR" ]}, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackName" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "PublicSubnet" : { "Type" : "AWS::EC2::Subnet", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "CidrBlock" : { "Fn::FindInMap" : [ "SubnetConfig", "Public", "CIDR" ]}, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackName" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "InternetGateway" : { "Type" : "AWS::EC2::InternetGateway", "Properties" : { "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackName" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "GatewayToInternet" : { "Type" : "AWS::EC2::VPCGatewayAttachment", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "InternetGatewayId" : { "Ref" : "InternetGateway" } } }, "PublicRouteTable" : { "Type" : "AWS::EC2::RouteTable", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackName" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "PublicRoute" : { "Type" : "AWS::EC2::Route", "DependsOn" : "GatewayToInternet", "Properties" : { "RouteTableId" : { "Ref" : "PublicRouteTable" }, "DestinationCidrBlock" : "0.0.0.0/0", "GatewayId" : { "Ref" : "InternetGateway" } } }, "PublicSubnetRouteTableAssociation" : { "Type" : "AWS::EC2::SubnetRouteTableAssociation", "Properties" : { "SubnetId" : { "Ref" : "PublicSubnet" }, "RouteTableId" : { "Ref" : "PublicRouteTable" } } }, "PublicNetworkAcl" : { "Type" : "AWS::EC2::NetworkAcl", "Properties" : { "VpcId" : { "Ref" : "VPC" }, "Tags" : [ { "Key" : "Application", "Value" : { "Ref" : "AWS::StackName" } }, { "Key" : "Network", "Value" : "Public" } ] } }, "InboundHTTPPublicNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PublicNetworkAcl" }, "RuleNumber" : "100", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "false", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "80", "To" : "80" } } }, "InboundHTTPSPublicNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PublicNetworkAcl" }, "RuleNumber" : "101", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "false", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "443", "To" : "443" } } }, "InboundEphemeralPublicNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PublicNetworkAcl" }, "RuleNumber" : "103", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "false", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "1024", "To" : "65535" } } }, "OutboundPublicNetworkAclEntry" : { "Type" : "AWS::EC2::NetworkAclEntry", "Properties" : { "NetworkAclId" : { "Ref" : "PublicNetworkAcl" }, "RuleNumber" : "100", "Protocol" : "6", "RuleAction" : "allow", "Egress" : "true", "CidrBlock" : "0.0.0.0/0", "PortRange" : { "From" : "0", "To" : "65535" } } }, "PublicSubnetNetworkAclAssociation" : { "Type" : "AWS::EC2::SubnetNetworkAclAssociation", "Properties" : { "SubnetId" : { "Ref" : "PublicSubnet" }, "NetworkAclId" : { "Ref" : "PublicNetworkAcl" } } }, "EC2MasterSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Block all of internet ingress; Amazon pokes necessary holes", "VpcId" : { "Ref" : "VPC" }, "SecurityGroupIngress" : [], "SecurityGroupEgress": [] } }, "EC2SlaveSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Block all of internet ingress; Amazon pokes necessary holes", "VpcId" : { "Ref" : "VPC" }, "SecurityGroupIngress" : [], "SecurityGroupEgress" : [] } }, "S3Endpoint" : { "Type" : "AWS::EC2::VPCEndpoint", "Properties" : { "PolicyDocument" : { "Version":"2012-10-17", "Statement":[{ "Effect":"Allow", "Principal": "*", "Action": "*", "Resource": "*" }] }, "RouteTableIds" : [ { "Ref" : "PublicRouteTable" } ], "ServiceName" : { "Fn::Join": [ "", [ "com.amazonaws.", { "Ref": "AWS::Region" }, ".s3" ] ] }, "VpcId" : {"Ref" : "VPC"} } } }, "Outputs" : { "PublicSubnetId" : { "Description" : "ID of subnet into which secure Rail-RNA job flows should be launched", "Value" : { "Ref" : "PublicSubnet" } }, "MasterSecurityGroupId" : { "Description" : "ID of security group that should be applied to MASTER EMR instances for all job flows when analyzing dbGaP data", "Value" : { "Ref" : "EC2MasterSecurityGroup" } }, "SlaveSecurityGroupId" : { "Description" : "ID of security group that should be applied to SLAVE EMR instances for all job flows when analyzing dbGaP data", "Value" : { "Ref" : "EC2SlaveSecurityGroup" } }, "SecureBucketName" : { "Description" : "Name of secure S3 bucket associated with stack; Rail-RNA job flows should write intermediate and output data to this bucket", "Value" : { "Ref" : "S3Bucket" } } } }