diff --git a/Transit-VPC/transit-vpc-primary-account.yaml b/Transit-VPC/transit-vpc-primary-account.yaml new file mode 100644 index 0000000..90b176e --- /dev/null +++ b/Transit-VPC/transit-vpc-primary-account.yaml @@ -0,0 +1,1978 @@ +--- +AWSTemplateFormatVersion: '2010-09-09' +Description: "Juniper vSRX Transit VPC: This template creates a dedicated transit VPC + with Juniper vSRX for routing traffic. ***NOTE*** You must first subscribe to the + appropriate Juniper VSRX marketplace BYOL or License Included AMI from the AWS Marketplace + before you launch this template. Version 3" +Parameters: + SshPublicKey: + Description: SSH public key to enable SSH access to the instances + Type: String + Default: Paste your public key here + AllowedSshIpAddress: + Description: Source IP address (CIDR notation) from which SSH to vSRXs is allowed + Type: String + Default: 0.0.0.0/0 + AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})" + ConstraintDescription: Enter valid CIDR to allow SSH to vSRX(s). Must be a valid + IP CIDR range of the form x.x.x.x/x + TerminationProtection: + Description: Enable termination protection on the VSRX EC2 instances to avoid + accidential VSRX termination? + Type: String + Default: 'Yes' + AllowedValues: + - 'Yes' + - 'No' + PreferredPathTag: + Description: Tag to use to configure a preferred VSRX VPN endpoint to control + traffic flow through the Transit VPC VSRX (e.g. when integrating with CPE). + Type: String + Default: transitvpc:preferred-path + SpokeTag: + Description: Tag to use to identify spoke VPCs to connect to Transit VPC. + Type: String + Default: transitvpc:spoke + SpokeTagValue: + Description: Tag value to use to identify spoke VPCs to connect to Transit VPC. + Type: String + Default: 'true' + BgpAsn: + Description: BGP ASN to use for Transit VPC. + Type: String + Default: '64512' + VpcCidr: + Description: CIDR block for Transit VPC. + Type: String + Default: 200.0.0.0/16 + PubSubnet11: + Description: Address range for Transit VPC subnet to be created in AZ1. + Type: String + Default: 200.0.254.0/24 + PubSubnet12: + Description: Address range for Transit VPC subnet to be created in AZ1. + Type: String + Default: 200.0.1.0/24 + PubSubnet21: + Description: Address range for Transit VPC subnet to be created in AZ2. + Type: String + Default: 200.0.253.0/24 + PubSubnet22: + Description: Address range for Transit VPC subnet to be created in AZ2. + Type: String + Default: 200.0.2.0/24 + VSRXType: + Description: Virtual machine size required for VSRX instances. + Type: String + Default: C4.Xlarge + AllowedValues: + - C4.Xlarge + LicenseModel: + Description: Choose between BYOL (Bring Your Own License) and License Included + license models. Remember to first subscribe the the appropriate Marketplace + AMI! + Type: String + Default: LicenseIncluded + AllowedValues: + - LicenseIncluded + - BYOL + S3Prefix: + Description: S3 prefix to append before S3 key names. + Type: String + Default: vpnconfigs/ + AdditionalAWSAccountArns: + Description: List of AWS Account ARNs to authorize access to VPN Config S3 bucket + (for example bucket and KMS key policies). + Type: CommaDelimitedList + Default: '' +Conditions: + AuthorizeAnotherAccount: !Not [ !Equals [!Select [ 0, !Ref AdditionalAWSAccountArns ], '']] + EnableTerm: !Equals [!Ref TerminationProtection, 'Yes'] +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Juniper VSRX Configuration + Parameters: + - VSRXType + - SshPublicKey + - LicenseModel + - TerminationProtection + - Label: + default: AWS Service Configuration + Parameters: + - S3Prefix + - AdditionalAWSAccountArns + - Label: + default: Network Configuration + Parameters: + - VpcCidr + - AllowedSshIpAddress + - PubSubnet11 + - PubSubnet12 + - PubSubnet21 + - PubSubnet22 + - BgpAsn + - SpokeTag + - SpokeTagValue + - PreferredPathTag + ParameterLabels: + BgpAsn: + default: Transit VPC BGP ASN + SpokeTag: + default: Spoke VPC Tag Name + SpokeTagValue: + default: Spoke VPC Tag Value + PreferredPathTag: + default: Preferred VPN Endpoint Tag Name + AllowedSshIpAddress: + default: Allowed IP Address to SSH from + VpcCidr: + default: Transit VPC CIDR Block + PubSubnet11: + default: vSRX1- 1st Subnet Network + PubSubnet12: + default: vSRX1- 2nd Subnet Network + PubSubnet21: + default: vSRX2- 1st Subnet Network + PubSubnet22: + default: vSRX2- 2nd Subnet Network + VSRXType: + default: vSRX Instance Size + SshPublicKey: + default: SSH Key to access VSRX + S3Prefix: + default: Prefix for S3 Objects + LicenseModel: + default: License Model + TerminationProtection: + default: Enable Termination Protection + AdditionalAWSAccountArns: + default: Additional AWS Account ID (Optional) +Mappings: + Function: + Configurator: + CodeLocation: juniper-transit-vpc-solution/transit-vpc-push-juniper-config.zip + CodeRegion: us-east-1 + Name: juniper-configurator + Description: 'Transit VPC: This function is invoked when a generic VPN configuration + is placed in an S3 bucket - it converts the generic information into Junos + OS specific commands and pushes the config to transit VPC routers.' + Runtime: python2.7 + Timeout: '300' + MemorySize: '128' + Poller: + CodeLocation: juniper-transit-vpc-solution/transit-vpc-poller.py + CodeRegion: us-east-1 + Name: vgw-poller + Description: 'Transit VPC: Poller function responsible for identifying specifically + tagged VGWs and creating VPN connections to transit VPC.' + Runtime: python2.7 + Timeout: '120' + MemorySize: '128' + FindReplace: + S3BucketID: "%BUCKET_NAME%" + S3PrefixID: "%PREFIX%" + Deliminator: "|" + vSRX: + UserName: root + PasswordLength: '15' + PrivateKey: prikey.pem + PublicKey: pubkey.pem + JunipervSRXAMI: + us-east-1: + BYOL: ami-4ca1fc37 + LicenseIncluded: ami-6119471a + us-east-2: + BYOL: ami-00230365 + LicenseIncluded: ami-14311171 + us-west-2: + BYOL: ami-3542584c + LicenseIncluded: ami-71b8a208 + us-west-1: + BYOL: ami-9186aff1 + LicenseIncluded: ami-db4d65bb + ca-central-1: + BYOL: ami-ab04bbcf + LicenseIncluded: ami-d60eb1b2 + eu-west-1: + BYOL: ami-2117ff58 + LicenseIncluded: ami-ef3bd096 + eu-west-2: + BYOL: ami-d76f7eb3 + LicenseIncluded: ami-3c021358 + eu-central-1: + BYOL: ami-5bdf7334 + LicenseIncluded: ami-4761cd28 + ap-south-1: + BYOL: ami-26f68e49 + LicenseIncluded: ami-46c1b929 + ap-southeast-1: + BYOL: ami-c5a331a6 + LicenseIncluded: ami-2cec714f + ap-southeast-2: + BYOL: ami-14c1de77 + LicenseIncluded: ami-49b2ad2a + ap-northeast-1: + BYOL: ami-02729164 + LicenseIncluded: ami-5f5fbd39 + ap-northeast-2: + BYOL: ami-2bbe6745 + LicenseIncluded: ami-3ca47d52 + sa-east-1: + BYOL: ami-0656216a + LicenseIncluded: ami-11a5d27d + PrefixListIdMap: + ap-south-1: + s3: pl-78a54011 + eu-west-1: + s3: pl-6da54004 + ap-southeast-1: + s3: pl-6fa54006 + ap-southeast-2: + s3: pl-6ca54005 + eu-central-1: + s3: pl-6ea54007 + ap-northeast-2: + s3: pl-78a54011 + ap-northeast-1: + s3: pl-61a54008 + us-east-1: + s3: pl-63a5400a + us-east-2: + s3: pl-7ba54012 + sa-east-1: + s3: pl-6aa54003 + us-west-1: + s3: pl-6ba54002 + us-west-2: + s3: pl-68a54001 + vSRXInstance: + C4.Xlarge: + Type: c4.xlarge + Bandwidth: '500000' +Resources: + VPNConfigS3Bucket: + Type: AWS::S3::Bucket + VPNConfigBucketPolicy: + Type: AWS::S3::BucketPolicy + Properties: + Bucket: + Ref: VPNConfigS3Bucket + PolicyDocument: + Statement: + - Sid: DenyUnEncryptedObjectUploads + Effect: Deny + Principal: "*" + Action: s3:PutObject + Resource: !Sub "arn:aws:s3:::${VPNConfigS3Bucket}/${S3Prefix}*" + Condition: + StringNotEquals: + s3:x-amz-server-side-encryption: aws:kms + - Fn::If: + - AuthorizeAnotherAccount + - Sid: AdditionalAccountAccess + Effect: Allow + Action: + - s3:GetObject + - s3:PutObject + - s3:PutObjectAcl + Resource: !Sub "arn:aws:s3:::${VPNConfigS3Bucket}/${S3Prefix}*" + Principal: + AWS: !Ref AdditionalAWSAccountArns + - !Ref AWS::NoValue + + KMSKey: + Type: AWS::KMS::Key + Properties: + Description: TransitVPC CMK for S3 SSE-KMS + KeyPolicy: + Version: '2012-10-17' + Id: transit-vpc-1 + Statement: + - Sid: Enable IAM User Permissions + Effect: Allow + Principal: + AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root" + Action: + - kms:* + Resource: "*" + - Sid: Allow use of the key + Effect: Allow + Principal: + AWS: + - !GetAtt SolutionHelperRole.Arn + - !GetAtt JuniperConfigFunctionRole.Arn + - !GetAtt TransitVpcPollerRole.Arn + Action: + - kms:Encrypt + - kms:Decrypt + - kms:ReEncrypt* + - kms:GenerateDataKey* + - kms:DescribeKey + Resource: "*" + - Fn::If: + - AuthorizeAnotherAccount + - Sid: AdditionalAccountAuthorization + Effect: Allow + Action: + - kms:Encrypt + - kms:Decrypt + - kms:ReEncrypt* + - kms:GenerateDataKey* + - kms:DescribeKey + Resource: "*" + Principal: + AWS: !Ref AdditionalAWSAccountArns + - !Ref AWS::NoValue + TransitVPCKeyAlias: + Type: AWS::KMS::Alias + Properties: + AliasName: alias/TransitVPCKey + TargetKeyId: + Ref: KMSKey + TransitVPC: + Type: AWS::EC2::VPC + Properties: + CidrBlock: + Ref: VpcCidr + Tags: + - Key: Name + Value: Transit VPC + VPCPubSub11: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: TransitVPC + CidrBlock: + Ref: PubSubnet11 + AvailabilityZone: + Fn::Select: + - '0' + - Fn::GetAZs: '' + Tags: + - Key: Network + Value: Public + - Key: Name + Value: Transit VPC Subnet1 + VPCPubSub12: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: TransitVPC + CidrBlock: + Ref: PubSubnet12 + AvailabilityZone: + Fn::Select: + - '0' + - Fn::GetAZs: '' + Tags: + - Key: Network + Value: Public + - Key: Name + Value: Transit VPC Subnet1 + VPCPubSub21: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: TransitVPC + CidrBlock: + Ref: PubSubnet21 + AvailabilityZone: + Fn::Select: + - '1' + - Fn::GetAZs: '' + Tags: + - Key: Network + Value: Public + - Key: Name + Value: Transit VPC Subnet2 + VPCPubSub22: + Type: AWS::EC2::Subnet + Properties: + VpcId: + Ref: TransitVPC + CidrBlock: + Ref: PubSubnet22 + AvailabilityZone: + Fn::Select: + - '1' + - Fn::GetAZs: '' + Tags: + - Key: Network + Value: Public + - Key: Name + Value: Transit VPC Subnet1 + IGW: + Type: AWS::EC2::InternetGateway + Properties: + Tags: + - Key: Name + Value: Transit VPC IGW + IGWToInternet: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: + Ref: TransitVPC + InternetGatewayId: + Ref: IGW + VPCRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: + Ref: TransitVPC + Tags: + - Key: Network + Value: Public + - Key: Name + Value: Transit VPC + VPCPublicRoute: + Type: AWS::EC2::Route + Properties: + RouteTableId: + Ref: VPCRouteTable + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: + Ref: IGW + S3Endpoint: + Type: AWS::EC2::VPCEndpoint + Properties: + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: "*" + Action: + - s3:* + Resource: + - "*" + RouteTableIds: + - Ref: VPCRouteTable + ServiceName: + Fn::Join: + - '' + - - com.amazonaws. + - Ref: AWS::Region + - ".s3" + VpcId: + Ref: TransitVPC + VPCPubSubnetRouteTableAssociation1: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: + Ref: VPCPubSub11 + RouteTableId: + Ref: VPCRouteTable + VPCPubSubnetRouteTableAssociation2: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: + Ref: VPCPubSub12 + RouteTableId: + Ref: VPCRouteTable + VPCPubSubnetRouteTableAssociation3: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: + Ref: VPCPubSub21 + RouteTableId: + Ref: VPCRouteTable + VPCPubSubnetRouteTableAssociation4: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: + Ref: VPCPubSub22 + RouteTableId: + Ref: VPCRouteTable + vSRXEip11: + Type: AWS::EC2::EIP + Properties: + Domain: vpc + vSRXEip12: + Type: AWS::EC2::EIP + Properties: + Domain: vpc + vSRXEip21: + Type: AWS::EC2::EIP + Properties: + Domain: vpc + vSRXEip22: + Type: AWS::EC2::EIP + Properties: + Domain: vpc + AssociateEIP11: + Type: AWS::EC2::EIPAssociation + Properties: + AllocationId: + Fn::GetAtt: + - vSRXEip11 + - AllocationId + NetworkInterfaceId: + Ref: vSRXInterface11 + AssociateEIP12: + Type: AWS::EC2::EIPAssociation + Properties: + AllocationId: + Fn::GetAtt: + - vSRXEip12 + - AllocationId + NetworkInterfaceId: + Ref: vSRXInterface12 + AssociateEIP21: + Type: AWS::EC2::EIPAssociation + Properties: + AllocationId: + Fn::GetAtt: + - vSRXEip21 + - AllocationId + NetworkInterfaceId: + Ref: vSRXInterface21 + AssociateEIP22: + Type: AWS::EC2::EIPAssociation + Properties: + AllocationId: + Fn::GetAtt: + - vSRXEip22 + - AllocationId + NetworkInterfaceId: + Ref: vSRXInterface22 + vSRXInterface11: + Type: AWS::EC2::NetworkInterface + Properties: + Description: vSRXRevenueInterface1 + SourceDestCheck: 'false' + GroupSet: + - Ref: VSRXSecurityGroup + SubnetId: + Ref: VPCPubSub11 + vSRXInterface12: + Type: AWS::EC2::NetworkInterface + Properties: + Description: vSRXRevenueInterface1 + SourceDestCheck: 'false' + GroupSet: + - Ref: VSRXSecurityGroup + SubnetId: + Ref: VPCPubSub12 + vSRXInterface21: + Type: AWS::EC2::NetworkInterface + Properties: + Description: vSRXRevenueInterface1 + SourceDestCheck: 'false' + GroupSet: + - Ref: VSRXSecurityGroup + SubnetId: + Ref: VPCPubSub21 + vSRXInterface22: + Type: AWS::EC2::NetworkInterface + Properties: + Description: vSRXRevenueInterface1 + SourceDestCheck: 'false' + GroupSet: + - Ref: VSRXSecurityGroup + SubnetId: + Ref: VPCPubSub22 + VpcvSRX1: + Type: AWS::EC2::Instance + Metadata: + Comment1: Launch Juniper VSRX1 + Properties: + InstanceType: + Fn::FindInMap: + - vSRXInstance + - Ref: VSRXType + - Type + DisableApiTermination: + Fn::If: + - EnableTerm + - true + - false + ImageId: + Fn::FindInMap: + - JunipervSRXAMI + - Ref: AWS::Region + - Ref: LicenseModel + NetworkInterfaces: + - NetworkInterfaceId: + Ref: vSRXInterface11 + DeviceIndex: '0' + - NetworkInterfaceId: + Ref: vSRXInterface12 + DeviceIndex: '1' + Tags: + - Key: Name + Value: Transit VPC VSRX1 + UserData: + Fn::Base64: + Fn::Join: + - "\n" + - - "#junos-config" + - groups { + - transit-vpc { + - system { + - host-name tvpc-vsrx1; + - root-authentication { + - 'encrypted-password "$1$ZUlES4dp$OUwWo1g7cLoV/aMWpHUnC/"; ## SECRET-DATA' + - Fn::Join: + - '' + - - 'ssh-rsa ' + - "\"" + - 'ssh-rsa ' + - Fn::GetAtt: + - CreateRsaKey + - PubKey + - "\"" + - "; " + - "## SECRET-DATA" + - Fn::Join: + - '' + - - 'ssh-rsa ' + - "\"" + - Ref: SshPublicKey + - "\"" + - "; " + - "## SECRET-DATA" + - "}" + - login { + - user transit { + - uid 2000; + - class super-user; + - authentication { + - 'encrypted-password "$5$EZJ9ab2R$aSIQgSH5G0mcuHvmiN1U.TzEhIF0zyerQEHmo/JI3m3"; + ## SECRET-DATA' + - Fn::Join: + - '' + - - 'ssh-rsa ' + - "\"" + - 'ssh-rsa ' + - Fn::GetAtt: + - CreateRsaKey + - PubKey + - "\"" + - "; " + - "## SECRET-DATA" + - "}" + - "}" + - "}" + - services { + - ssh { + - no-passwords; + - connection-limit 1; + - "}" + - netconf { + - ssh; + - "}" + - web-management { + - https { + - system-generated-certificate; + - "}" + - "}" + - "}" + - "}" + - interfaces { + - fxp0 { + - unit 0 { + - family inet { + - dhcp; + - "}" + - "}" + - "}" + - "}" + - "}" + - "}" + - apply-groups transit-vpc; + - system { + - host-name tvpc-vsrx1; + - root-authentication { + - 'encrypted-password "$5$EZJ9ab2R$aSIQgSH5G0mcuHvmiN1U.TzEhIF0zyerQEHmo/JI3m3"; + ## SECRET-DATA' + - "}" + - services { + - ssh; + - netconf { + - ssh; + - "}" + - web-management { + - https { + - system-generated-certificate; + - "}" + - "}" + - "}" + - syslog { + - user * { + - any emergency; + - "}" + - file messages { + - any notice; + - authorization info; + - "}" + - file interactive-commands { + - interactive-commands any; + - "}" + - "}" + - license { + - autoupdate { + - url https://ae1.juniper.net/junos/key_retrieval; + - "}" + - "}" + - "}" + - security { + - screen { + - ids-option untrust-screen { + - icmp { + - ping-death; + - "}" + - ip { + - source-route-option; + - tear-drop; + - "}" + - tcp { + - syn-flood { + - alarm-threshold 1024; + - attack-threshold 200; + - source-threshold 1024; + - destination-threshold 2048; + - timeout 20; + - "}" + - land; + - "}" + - "}" + - "}" + - policies { + - from-zone trust to-zone trust { + - policy default-permit { + - match { + - source-address any; + - destination-address any; + - application any; + - "}" + - then { + - permit; + - "}" + - "}" + - "}" + - from-zone trust to-zone untrust { + - policy default-permit { + - match { + - source-address any; + - destination-address any; + - application any; + - "}" + - then { + - permit; + - "}" + - "}" + - "}" + - global { + - policy intervpc { + - match { + - source-address any; + - destination-address any; + - application any; + - "}" + - then { + - permit; + - "}" + - "}" + - policy intervpn { + - match { + - source-address any; + - destination-address any; + - application any; + - "}" + - then { + - permit; + - "}" + - "}" + - policy dc-2-vpc { + - match { + - source-address any; + - destination-address any; + - application any; + - from-zone trust; + - "}" + - then { + - permit; + - "}" + - "}" + - policy vpc-2-dc { + - match { + - source-address any; + - destination-address any; + - application any; + - to-zone trust; + - "}" + - then { + - permit; + - "}" + - "}" + - "}" + - "}" + - zones { + - security-zone trust { + - tcp-rst; + - interfaces { + - ge-0/0/1.0; + - "}" + - "}" + - security-zone untrust { + - screen untrust-screen; + - host-inbound-traffic { + - system-services { + - ike; + - "}" + - protocols { + - bgp; + - "}" + - "}" + - interfaces { + - ge-0/0/0.0; + - "}" + - "}" + - "}" + - "}" + - interfaces { + - ge-0/0/0 { + - unit 0 { + - family inet { + - Fn::Join: + - '' + - - 'address ' + - Fn::GetAtt: + - vSRXInterface12 + - PrimaryPrivateIpAddress + - "/" + - Fn::Select: + - '1' + - Fn::Split: + - "/" + - Ref: PubSubnet12 + - ";" + - "}" + - "}" + - "}" + - ge-0/0/1 { + - unit 0 { + - family inet; + - "}" + - "}" + - "}" + - policy-options { + - policy-statement DC { + - term reject-default { + - from { + - instance DC; + - protocol static; + - " route-filter 0.0.0.0/0 exact;" + - "}" + - then reject; + - "}" + - term accept-all { + - from instance DC; + - then accept; + - "}" + - "}" + - policy-statement EXPORT-DEFAULT { + - term default { + - from { + - route-filter 0.0.0.0/0 exact; + - "}" + - then accept; + - "}" + - term reject { + - then reject; + - "}" + - "}" + - policy-statement send-default { + - from { + - protocol static; + - route-filter 0.0.0.0/0 exact; + - "}" + - then accept; + - "}" + - "}" + - routing-instances { + - DC { + - instance-type virtual-router; + - interface ge-0/0/1.0; + - routing-options { + - static { + - route 0.0.0.0/0 next-table transit.inet.0; + - "}" + - "}" + - "}" + - ge-routing { + - instance-type virtual-router; + - interface ge-0/0/0.0; + - "}" + - transit { + - instance-type forwarding; + - routing-options { + - instance-import DC; + - "}" + - "}" + - "}" + DependsOn: IGW + VpcvSRX2: + Type: AWS::EC2::Instance + Metadata: + Comment1: Launch Juniper VSRX2 + Properties: + InstanceType: + Fn::FindInMap: + - vSRXInstance + - Ref: VSRXType + - Type + DisableApiTermination: + Fn::If: + - EnableTerm + - true + - false + ImageId: + Fn::FindInMap: + - JunipervSRXAMI + - Ref: AWS::Region + - Ref: LicenseModel + NetworkInterfaces: + - NetworkInterfaceId: + Ref: vSRXInterface21 + DeviceIndex: '0' + - NetworkInterfaceId: + Ref: vSRXInterface22 + DeviceIndex: '1' + Tags: + - Key: Name + Value: Transit VPC VSRX2 + UserData: + Fn::Base64: + Fn::Join: + - "\n" + - - "#junos-config" + - groups { + - transit-vpc { + - system { + - host-name tvpc-vsrx2; + - root-authentication { + - 'encrypted-password "$1$ZUlES4dp$OUwWo1g7cLoV/aMWpHUnC/"; ## SECRET-DATA' + - Fn::Join: + - '' + - - 'ssh-rsa ' + - "\"" + - 'ssh-rsa ' + - Fn::GetAtt: + - CreateRsaKey + - PubKey + - "\"" + - "; " + - "## SECRET-DATA" + - Fn::Join: + - '' + - - 'ssh-rsa ' + - "\"" + - Ref: SshPublicKey + - "\"" + - "; " + - "## SECRET-DATA" + - "}" + - login { + - user transit { + - uid 2000; + - class super-user; + - authentication { + - 'encrypted-password "$5$EZJ9ab2R$aSIQgSH5G0mcuHvmiN1U.TzEhIF0zyerQEHmo/JI3m3"; + ## SECRET-DATA' + - Fn::Join: + - '' + - - 'ssh-rsa ' + - "\"" + - 'ssh-rsa ' + - Fn::GetAtt: + - CreateRsaKey + - PubKey + - "\"" + - "; " + - "## SECRET-DATA" + - "}" + - "}" + - "}" + - services { + - ssh { + - no-passwords; + - connection-limit 1; + - "}" + - netconf { + - ssh; + - "}" + - web-management { + - https { + - system-generated-certificate; + - "}" + - "}" + - "}" + - "}" + - interfaces { + - fxp0 { + - unit 0 { + - family inet { + - dhcp; + - "}" + - "}" + - "}" + - "}" + - "}" + - "}" + - apply-groups transit-vpc; + - system { + - host-name tvpc-vsrx2; + - root-authentication { + - 'encrypted-password "$5$EZJ9ab2R$aSIQgSH5G0mcuHvmiN1U.TzEhIF0zyerQEHmo/JI3m3"; + ## SECRET-DATA' + - "}" + - services { + - ssh; + - netconf { + - ssh; + - "}" + - web-management { + - https { + - system-generated-certificate; + - "}" + - "}" + - "}" + - syslog { + - user * { + - any emergency; + - "}" + - file messages { + - any notice; + - authorization info; + - "}" + - file interactive-commands { + - interactive-commands any; + - "}" + - "}" + - license { + - autoupdate { + - url https://ae1.juniper.net/junos/key_retrieval; + - "}" + - "}" + - "}" + - security { + - screen { + - ids-option untrust-screen { + - icmp { + - ping-death; + - "}" + - ip { + - source-route-option; + - tear-drop; + - "}" + - tcp { + - syn-flood { + - alarm-threshold 1024; + - attack-threshold 200; + - source-threshold 1024; + - destination-threshold 2048; + - timeout 20; + - "}" + - land; + - "}" + - "}" + - "}" + - policies { + - from-zone trust to-zone trust { + - policy default-permit { + - match { + - source-address any; + - destination-address any; + - application any; + - "}" + - then { + - permit; + - "}" + - "}" + - "}" + - from-zone trust to-zone untrust { + - policy default-permit { + - match { + - source-address any; + - destination-address any; + - application any; + - "}" + - then { + - permit; + - "}" + - "}" + - "}" + - global { + - policy intervpc { + - match { + - source-address any; + - destination-address any; + - application any; + - "}" + - then { + - permit; + - "}" + - "}" + - policy intervpn { + - match { + - source-address any; + - destination-address any; + - application any; + - "}" + - then { + - permit; + - "}" + - "}" + - policy dc-2-vpc { + - match { + - source-address any; + - destination-address any; + - application any; + - from-zone trust; + - "}" + - then { + - permit; + - "}" + - "}" + - policy vpc-2-dc { + - match { + - source-address any; + - destination-address any; + - application any; + - to-zone trust; + - "}" + - then { + - permit; + - "}" + - "}" + - "}" + - "}" + - zones { + - security-zone trust { + - tcp-rst; + - interfaces { + - ge-0/0/1.0; + - "}" + - "}" + - security-zone untrust { + - screen untrust-screen; + - host-inbound-traffic { + - system-services { + - ike; + - "}" + - protocols { + - bgp; + - "}" + - "}" + - interfaces { + - ge-0/0/0.0; + - "}" + - "}" + - "}" + - "}" + - interfaces { + - ge-0/0/0 { + - unit 0 { + - family inet { + - Fn::Join: + - '' + - - 'address ' + - Fn::GetAtt: + - vSRXInterface22 + - PrimaryPrivateIpAddress + - "/" + - Fn::Select: + - '1' + - Fn::Split: + - "/" + - Ref: PubSubnet22 + - ";" + - "}" + - "}" + - "}" + - ge-0/0/1 { + - unit 0 { + - family inet; + - "}" + - "}" + - "}" + - policy-options { + - policy-statement DC { + - term reject-default { + - from { + - instance DC; + - protocol static; + - " route-filter 0.0.0.0/0 exact;" + - "}" + - then reject; + - "}" + - term accept-all { + - from instance DC; + - then accept; + - "}" + - "}" + - policy-statement EXPORT-DEFAULT { + - term default { + - from { + - route-filter 0.0.0.0/0 exact; + - "}" + - then accept; + - "}" + - term reject { + - then reject; + - "}" + - "}" + - policy-statement send-default { + - from { + - protocol static; + - route-filter 0.0.0.0/0 exact; + - "}" + - then accept; + - "}" + - "}" + - routing-instances { + - DC { + - instance-type virtual-router; + - interface ge-0/0/1.0; + - routing-options { + - static { + - route 0.0.0.0/0 next-table transit.inet.0; + - "}" + - "}" + - "}" + - ge-routing { + - instance-type virtual-router; + - interface ge-0/0/0.0; + - "}" + - transit { + - instance-type forwarding; + - routing-options { + - instance-import DC; + - "}" + - "}" + - "}" + DependsOn: IGW + SolutionHelperRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + Path: "/" + SolutionHelperRolePolicy: + Type: AWS::IAM::Policy + Properties: + Roles: + - Ref: SolutionHelperRole + PolicyName: Solution_Helper_Permissions + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + Fn::Join: + - '' + - - 'arn:aws:logs:' + - Ref: AWS::Region + - ":" + - Ref: AWS::AccountId + - ":log-group:/aws/lambda/*" + - Effect: Allow + Action: + - kms:Encrypt + - kms:Decrypt + - kms:ReEncrypt* + - kms:GenerateDataKey* + - kms:DescribeKey + Resource: + Fn::Join: + - '' + - - 'arn:aws:kms:' + - Ref: AWS::Region + - ":" + - Ref: AWS::AccountId + - ":key/" + - Ref: KMSKey + - Effect: Allow + Action: + - s3:PutBucketNotification + Resource: + Fn::Join: + - '' + - - 'arn:aws:s3:::' + - Ref: VPNConfigS3Bucket + - Effect: Allow + Action: + - lambda:* + - events:* + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + - ec2:DescribeVpcs + Resource: "*" + - Effect: Allow + Action: + - iam:PassRole + Resource: + - Fn::GetAtt: + - JuniperConfigFunctionRole + - Arn + - Fn::GetAtt: + - TransitVpcPollerRole + - Arn + - Effect: Allow + Action: s3:* + Resource: "*" + SolutionHelper: + Type: AWS::Lambda::Function + DependsOn: SolutionHelperRolePolicy + Properties: + Handler: solution-helper.lambda_handler + Role: + Fn::GetAtt: + - SolutionHelperRole + - Arn + Description: 'Transit VPC: CloudFormation custom resource function invoked during + transit VPC CloudFormation create, update, and delete stack operations.' + Code: + S3Bucket: + Fn::Join: + - '' + - - solutions- + - Ref: AWS::Region + S3Key: library/solution-helper/v3/solution-helper.zip + Runtime: python2.7 + Timeout: '60' + CreateRsaKey: + Type: Custom::LoadLambda + Properties: + ServiceToken: + Fn::GetAtt: + - SolutionHelper + - Arn + Region: + Ref: AWS::Region + CreateSshKey: + Fn::Join: + - '' + - - "{ 'Bucket' : '" + - Ref: VPNConfigS3Bucket + - "', " + - "'SSEKMSKeyId' : 'arn:aws:kms:" + - Ref: AWS::Region + - ":" + - Ref: AWS::AccountId + - ":key/" + - Ref: KMSKey + - "', " + - "'PrivateKey' : '" + - Ref: S3Prefix + - Fn::FindInMap: + - Function + - vSRX + - PrivateKey + - "', " + - "'PublicKey' : '" + - Ref: S3Prefix + - Fn::FindInMap: + - Function + - vSRX + - PublicKey + - "' " + - "}" + CreateRandomPassword: + Type: Custom::LoadLambda + Properties: + ServiceToken: + Fn::GetAtt: + - SolutionHelper + - Arn + Region: + Ref: AWS::Region + CreateRandomPassword: + Fn::FindInMap: + - Function + - vSRX + - PasswordLength + RandomPasswordSpecialCharacters: 'False' + JuniperConfigFunctionRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + Path: "/" + JuniperConfigFunctionRolePolicy: + Type: AWS::IAM::Policy + Properties: + Roles: + - Ref: JuniperConfigFunctionRole + PolicyName: Juniper_Config_Permissions + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + Fn::Join: + - '' + - - 'arn:aws:logs:' + - Ref: AWS::Region + - ":" + - Ref: AWS::AccountId + - ":log-group:/aws/lambda/*" + - Effect: Allow + Action: + - ec2:CreateNetworkInterface + - ec2:DescribeNetworkInterfaces + - ec2:DetachNetworkInterface + - ec2:DeleteNetworkInterface + Resource: "*" + - Effect: Allow + Action: + - kms:Encrypt + - kms:Decrypt + - kms:ReEncrypt* + - kms:GenerateDataKey* + - kms:DescribeKey + Resource: + Fn::Join: + - '' + - - 'arn:aws:kms:' + - Ref: AWS::Region + - ":" + - Ref: AWS::AccountId + - ":key/" + - Ref: KMSKey + - Effect: Allow + Action: + - s3:PutObject + - s3:GetObject + Resource: + Fn::Join: + - '' + - - 'arn:aws:s3:::' + - Ref: VPNConfigS3Bucket + - "/" + - Ref: S3Prefix + - "*" + JuniperConfigFunct: + Type: Custom::LoadLambda + Properties: + ServiceToken: + Fn::GetAtt: + - SolutionHelper + - Arn + Region: + Ref: AWS::Region + LambdaCode: + Fn::FindInMap: + - Function + - Configurator + - CodeLocation + LambdaCodeRegion: + Fn::FindInMap: + - Function + - Configurator + - CodeRegion + FunctionName: + Fn::Join: + - '' + - - Ref: AWS::StackName + - "-" + - Fn::FindInMap: + - Function + - Configurator + - Name + Role: + Fn::GetAtt: + - JuniperConfigFunctionRole + - Arn + Runtime: + Fn::FindInMap: + - Function + - Configurator + - Runtime + Description: + Fn::FindInMap: + - Function + - Configurator + - Description + Timeout: + Fn::FindInMap: + - Function + - Configurator + - Timeout + MemorySize: + Fn::FindInMap: + - Function + - Configurator + - MemorySize + VpcConfig: + Fn::Join: + - '' + - - "{ 'SubnetIds': [" + - "'" + - Ref: VPCPubSub11 + - "'," + - "'" + - Ref: VPCPubSub21 + - "']," + - "'SecurityGroupIds': [" + - "'" + - Ref: JuniperConfigSecurityGroup + - "']" + - "}" + S3Event: + Fn::Join: + - '' + - - "{ 'Bucket' : '" + - Ref: VPNConfigS3Bucket + - "', " + - "'EventPattern' : {" + - "'LambdaFunctionConfigurations' : [ {" + - "'LambdaFunctionArn': 'Replace_by_SolutionHelper'," + - "'Events': ['s3:ObjectCreated:Put' ]," + - "'Filter': {" + - "'Key': {" + - "'FilterRules': [ {" + - "'Name': 'prefix'," + - "'Value': '" + - Ref: S3Prefix + - "'" + - "}, {" + - "'Name': 'suffix'," + - "'Value': '.conf'" + - "} ] } }" + - "} ] }" + - "}" + StoreInS3KMS: + Fn::Join: + - '' + - - "[{ 'Bucket' : '" + - Ref: VPNConfigS3Bucket + - "', " + - "'Key' : '" + - Ref: S3Prefix + - 'transit_vpc_config.txt'', ' + - "'SSEKMSKeyId' : 'arn:aws:kms:" + - Ref: AWS::Region + - ":" + - Ref: AWS::AccountId + - ":key/" + - Ref: KMSKey + - "', " + - '''Body'': "{' + - "'UUID':'" + - Fn::GetAtt: + - CreateUniqueID + - UUID + - "'," + - "'EIP1':'" + - Ref: vSRXEip12 + - "'," + - "'EIP2':'" + - Ref: vSRXEip22 + - "'," + - "'PIP1':'" + - Fn::GetAtt: + - VpcvSRX1 + - PrivateIp + - "'," + - "'PIP2':'" + - Fn::GetAtt: + - VpcvSRX2 + - PrivateIp + - "'," + - "'SUB1':'" + - Ref: PubSubnet12 + - "'," + - "'SUB2':'" + - Ref: PubSubnet22 + - "'," + - "'Testkey':'" + - Ref: SshPublicKey + - "'," + - "'BGP_ASN':" + - Ref: BgpAsn + - "," + - "'PREFERRED_PATH_TAG':'" + - Ref: PreferredPathTag + - "'," + - "'HUB_TAG':'" + - Ref: SpokeTag + - "'," + - "'HUB_TAG_VALUE':'" + - Ref: SpokeTagValue + - "'," + - "'USER_NAME':'" + - Fn::FindInMap: + - Function + - vSRX + - UserName + - "'," + - "'PRIVATE_KEY':'" + - Fn::FindInMap: + - Function + - vSRX + - PrivateKey + - "'," + - "'PUBLIC_KEY':'" + - Fn::GetAtt: + - CreateRsaKey + - PubKey + - "'," + - "'PASSWORD':'" + - Fn::GetAtt: + - CreateRandomPassword + - Password + - "'," + - "'KMS_KEY':'arn:aws:kms:" + - Ref: AWS::Region + - ":" + - Ref: AWS::AccountId + - ":key/" + - Ref: KMSKey + - "'" + - '}"' + - "}]" + TransitVpcPollerRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + Path: "/" + TransitVpcPollerRolePolicy: + Type: AWS::IAM::Policy + Properties: + Roles: + - Ref: TransitVpcPollerRole + PolicyName: Transit_VPC_Poller_Function_Permissions + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: + Fn::Join: + - '' + - - 'arn:aws:logs:' + - Ref: AWS::Region + - ":" + - Ref: AWS::AccountId + - ":log-group:/aws/lambda/*" + - Effect: Allow + Action: + - ec2:Describe* + - ec2:CreateTags + - ec2:CreateCustomerGateway + - ec2:DeleteCustomerGateway + - ec2:CreateVpnConnection + - ec2:DeleteVpnConnection + Resource: "*" + - Effect: Allow + Action: + - kms:Encrypt + - kms:Decrypt + - kms:ReEncrypt* + - kms:GenerateDataKey* + - kms:DescribeKey + Resource: + Fn::Join: + - '' + - - 'arn:aws:kms:' + - Ref: AWS::Region + - ":" + - Ref: AWS::AccountId + - ":key/" + - Ref: KMSKey + - Effect: Allow + Action: + - s3:PutObject + - s3:PutObjectAcl + - s3:GetObject + Resource: + Fn::Join: + - '' + - - 'arn:aws:s3:::' + - Ref: VPNConfigS3Bucket + - "/" + - Ref: S3Prefix + - "*" + PollerFunct: + DependsOn: JuniperConfigFunct + Type: Custom::LoadLambda + Properties: + ServiceToken: + Fn::GetAtt: + - SolutionHelper + - Arn + Region: + Ref: AWS::Region + LambdaCode: + Fn::FindInMap: + - Function + - Poller + - CodeLocation + LambdaCodeRegion: + Fn::FindInMap: + - Function + - Poller + - CodeRegion + Deliminator: + Fn::FindInMap: + - Function + - FindReplace + - Deliminator + FunctionName: + Fn::Join: + - '' + - - Ref: AWS::StackName + - "-" + - Fn::FindInMap: + - Function + - Poller + - Name + Role: + Fn::GetAtt: + - TransitVpcPollerRole + - Arn + CloudWatchEvent: + Fn::Join: + - '' + - - "{ 'RuleName' : '" + - Ref: AWS::StackName + - "-VGW-Poller-1min', " + - "'ScheduleExpression' : 'cron(* * * * ? *)'," + - "'Description': 'Transit VPC: Rule to trigger VGW-Poller every minute + to find VGWs that need to be attached to the transit VPC.' }" + Runtime: + Fn::FindInMap: + - Function + - Poller + - Runtime + Description: + Fn::FindInMap: + - Function + - Poller + - Description + Timeout: + Fn::FindInMap: + - Function + - Poller + - Timeout + MemorySize: + Fn::FindInMap: + - Function + - Poller + - MemorySize + FindReplace: + Fn::Join: + - '' + - - Fn::FindInMap: + - Function + - FindReplace + - S3BucketID + - Fn::FindInMap: + - Function + - FindReplace + - Deliminator + - Ref: VPNConfigS3Bucket + - "," + - Fn::FindInMap: + - Function + - FindReplace + - S3PrefixID + - Fn::FindInMap: + - Function + - FindReplace + - Deliminator + - Ref: S3Prefix + VSRXSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: VSRX Security Group Rules + VpcId: + Ref: TransitVPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: '22' + ToPort: '22' + CidrIp: + Ref: AllowedSshIpAddress + - IpProtocol: icmp + FromPort: '8' + ToPort: "-1" + CidrIp: + Ref: AllowedSshIpAddress + SecurityGroupEgress: + - IpProtocol: "-1" + FromPort: '0' + ToPort: '65535' + CidrIp: 0.0.0.0/0 + SSHtoVSRXSecurityGroup: + Type: AWS::EC2::SecurityGroupIngress + Properties: + IpProtocol: tcp + FromPort: '22' + ToPort: '22' + SourceSecurityGroupId: + Fn::GetAtt: + - JuniperConfigSecurityGroup + - GroupId + GroupId: + Fn::GetAtt: + - VSRXSecurityGroup + - GroupId + JuniperConfigSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Transit VPC Automation Security Group Rules + VpcId: + Ref: TransitVPC + SSHtoVSRX: + Type: AWS::EC2::SecurityGroupEgress + Properties: + IpProtocol: tcp + FromPort: '22' + ToPort: '22' + DestinationSecurityGroupId: + Fn::GetAtt: + - VSRXSecurityGroup + - GroupId + GroupId: + Fn::GetAtt: + - JuniperConfigSecurityGroup + - GroupId + HTTPSToVPCEndpoint: + Type: AWS::EC2::SecurityGroupEgress + Properties: + IpProtocol: tcp + FromPort: '443' + ToPort: '443' + DestinationPrefixListId: + Fn::FindInMap: + - PrefixListIdMap + - Ref: AWS::Region + - s3 + GroupId: + Fn::GetAtt: + - JuniperConfigSecurityGroup + - GroupId + VSRX1RecoveryAlarm: + Type: AWS::CloudWatch::Alarm + Properties: + AlarmDescription: Trigger a recovery when VSRX1 instance status check fails + for 15 consecutive minutes. + Namespace: AWS/EC2 + MetricName: StatusCheckFailed_System + Statistic: Minimum + Period: '60' + EvaluationPeriods: '35' + ComparisonOperator: GreaterThanThreshold + Threshold: '0' + AlarmActions: + - Fn::Join: + - '' + - - 'arn:aws:automate:' + - Ref: AWS::Region + - ":ec2:recover" + Dimensions: + - Name: InstanceId + Value: + Ref: VpcvSRX1 + VSRX2RecoveryAlarm: + Type: AWS::CloudWatch::Alarm + Properties: + AlarmDescription: Trigger a recovery when VSRX2 instance status check fails + for 15 consecutive minutes. + Namespace: AWS/EC2 + MetricName: StatusCheckFailed_System + Statistic: Minimum + Period: '60' + EvaluationPeriods: '35' + ComparisonOperator: GreaterThanThreshold + Threshold: '0' + AlarmActions: + - Fn::Join: + - '' + - - 'arn:aws:automate:' + - Ref: AWS::Region + - ":ec2:recover" + Dimensions: + - Name: InstanceId + Value: + Ref: VpcvSRX2 + CreateUniqueID: + Type: Custom::LoadLambda + Properties: + ServiceToken: + Fn::GetAtt: + - SolutionHelper + - Arn + Region: + Ref: AWS::Region + CreateUniqueID: 'true' +Outputs: + VSRX1: + Description: IP Address for VSRX1 + Value: + Fn::GetAtt: + - VpcvSRX1 + - PublicIp + VSRX2: + Description: IP Address for VSRX2 + Value: + Fn::GetAtt: + - VpcvSRX2 + - PublicIp + ConfigS3Bucket: + Description: S3 bucket for storing VPN configuration information. + Value: + Ref: VPNConfigS3Bucket + BucketPrefix: + Description: S3 prefix for storing VPN configuration information. + Value: + Ref: S3Prefix + SpokeVPCTag: + Description: Tag used to identify spoke VPCs. + Value: + Ref: SpokeTag + SpokeVPCTagValue: + Description: Tag valued used to idenfity spoke VPCs. + Value: + Ref: SpokeTagValue + PreferredPathTagName: + Description: Tag used to identify the spoke VPC preferred path. + Value: + Ref: PreferredPathTag + UUID: + Description: Newly created random UUID. + Value: + Fn::GetAtt: + - CreateUniqueID + - UUID diff --git a/Transit-VPC/transit-vpc-second-account.yaml b/Transit-VPC/transit-vpc-second-account.yaml new file mode 100644 index 0000000..741b7bc --- /dev/null +++ b/Transit-VPC/transit-vpc-second-account.yaml @@ -0,0 +1,224 @@ +--- +AWSTemplateFormatVersion: '2010-09-09' +Description: "(SO0001p) - Transit VPC: This template creates a TransitVPC poller function + to find spoke VPCs to add to the transit network." +Parameters: + BucketName: + Description: Name of the bucket used to store transit VPC configuration files. + Type: String + Default: transit-vpc + BucketPrefix: + Description: S3 object prefix for storing VPN configuration. + Type: String + Default: vpnconfigs/ +Mappings: + Function: + Poller: + CodeLocation: juniper-transit-vpc-solution/transit-vpc-poller.py + Name: vgw-poller + Description: 'Transit VPC: Poller function responsible for identifying specifically + tagged VGWs and creating VPN connections to transit VPC.' + Runtime: python2.7 + Timeout: '120' + MemorySize: '128' + FindReplace: + S3BucketID: "%BUCKET_NAME%" + S3PrefixID: "%PREFIX%" + Deliminator: "|" +Resources: + SolutionHelperRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + Path: "/" + Policies: + - PolicyName: Solution_Helper_Permissions + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: "*" + - Effect: Allow + Action: + - lambda:* + - events:* + - iam:PassRole + - s3:GetObject + - s3:PutObject + - s3:DeleteObject + - s3:PutBucketNotification + - ec2:DescribeSecurityGroups + - ec2:DescribeSubnets + Resource: "*" + SolutionHelper: + Type: AWS::Lambda::Function + Properties: + Handler: solution-helper.lambda_handler + Role: + Fn::GetAtt: + - SolutionHelperRole + - Arn + Description: 'Transit VPC: CloudFormation custom resource function invoked during + transit VPC CloudFormation create, update, and delete stack operations.' + Code: + S3Bucket: + Fn::Join: + - '' + - - solutions- + - Ref: AWS::Region + S3Key: library/solution-helper/v2/solution-helper.zip + Runtime: python2.7 + Timeout: '60' + TransitVpcPollerRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + Path: "/" + Policies: + - PolicyName: My_Lambda_Function_Permissions + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - logs:CreateLogGroup + - logs:CreateLogStream + - logs:PutLogEvents + Resource: "*" + - Effect: Allow + Action: + - ec2:Describe* + - ec2:CreateTags + - ec2:CreateCustomerGateway + - ec2:DeleteCustomerGateway + - ec2:CreateVpnConnection + - ec2:DeleteVpnConnection + Resource: "*" + - Effect: Allow + Action: + - kms:Decrypt + - kms:GenerateDataKey* + - kms:Encrypt + Resource: "*" + - Effect: Allow + Action: s3:* + Resource: "*" + PollerFunct: + Type: Custom::LoadLambda + Properties: + ServiceToken: + Fn::GetAtt: + - SolutionHelper + - Arn + Region: + Ref: AWS::Region + LambdaCode: + Fn::FindInMap: + - Function + - Poller + - CodeLocation + Deliminator: + Fn::FindInMap: + - Function + - FindReplace + - Deliminator + FunctionName: + Fn::Join: + - '' + - - Ref: AWS::StackName + - "-" + - Fn::FindInMap: + - Function + - Poller + - Name + Role: + Fn::GetAtt: + - TransitVpcPollerRole + - Arn + CloudWatchEvent: + Fn::Join: + - '' + - - "{ 'RuleName' : '" + - Ref: AWS::StackName + - "-VGW-Poller-1min', " + - "'ScheduleExpression' : 'cron(* * * * ? *)'," + - "'Description': 'Transit VPC: Rule to trigger VGW-Poller every minute + to find VGWs that need to be attached to the transit VPC.' }" + Runtime: + Fn::FindInMap: + - Function + - Poller + - Runtime + Description: + Fn::FindInMap: + - Function + - Poller + - Description + Timeout: + Fn::FindInMap: + - Function + - Poller + - Timeout + MemorySize: + Fn::FindInMap: + - Function + - Poller + - MemorySize + FindReplace: + Fn::Join: + - '' + - - Fn::FindInMap: + - Function + - FindReplace + - S3BucketID + - Fn::FindInMap: + - Function + - FindReplace + - Deliminator + - Ref: BucketName + - "," + - Fn::FindInMap: + - Function + - FindReplace + - S3PrefixID + - Fn::FindInMap: + - Function + - FindReplace + - Deliminator + - Ref: BucketPrefix +Outputs: + PollerFunction: + Description: New Lambda function name. + Value: + Fn::FindInMap: + - Function + - Poller + - Name + PollerFunctionARN: + Description: ARN for new Lambda function. + Value: + Fn::GetAtt: + - PollerFunct + - FunctionArn + PollerRoleARN: + Description: ARN for poller function role. + Value: + Fn::GetAtt: + - TransitVpcPollerRole + - Arn