# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. AWSTemplateFormatVersion: '2010-09-09' Description: strongSwan VPN Gateway as an EC2 Instance Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: System Classification Parameters: - pOrg - pSystem - pApp - Label: default: System Environment Parameters: - pEnvPurpose - Label: default: VPN Tunnel 1 Parameters: - pTunnel1Psk - pTunnel1VgwOutsideIpAddress - pTunnel1VgwInsideCidr - pTunnel1CgwInsideCidr - pTunnel1BgpAsn - pTunnel1BgpNeighborIpAddress - Label: default: VPN Tunnel 2 Parameters: - pTunnel2Psk - pTunnel2VgwOutsideIpAddress - pTunnel2VgwInsideCidr - pTunnel2CgwInsideCidr - pTunnel2BgpAsn - pTunnel2BgpNeighborIpAddress - Label: default: Local Network Configuration Parameters: - pVpcId - pVpcCidr - pSubnetId - pUseElasticIp - pEipAllocationId - pLocalBgpAsn - Label: default: EC2 Parameters: - pAmiId - pInstanceType ParameterLabels: pOrg: default: Organization Identifier pSystem: default: System Identifier pApp: default: Application Identifier pEnvPurpose: default: Environment Purpose pTunnel1Psk: default: VPN Tunnel 1 Pre-Shared Key pTunnel1VgwOutsideIpAddress: default: VPN Tunnel 1 Virtual Private Gateway Outside IP Address pTunnel1VgwInsideCidr: default: VPN Tunnel 1 Virtual Private Gateway Inside CIDR pTunnel1CgwInsideCidr: default: VPN Tunnel 1 Customer Gateway Inside CIDR pTunnel1BgpAsn: default: VPN Tunnel 1 BGP ASN pTunnel1BgpNeighborIpAddress: default: VPN Tunnel 1 BGP Neighbor IP Address pTunnel2Psk: default: VPN Tunnel 2 Pre-Shared Key pTunnel2VgwOutsideIpAddress: default: VPN Tunnel 2 Virtual Private Gateway Outside IP Address pTunnel2VgwInsideCidr: default: VPN Tunnel 2 Virtual Private Gateway Inside CIDR pTunnel2CgwInsideCidr: default: VPN Tunnel 2 Customer Gateway Inside CIDR pTunnel2BgpAsn: default: VPN Tunnel 2 BGP ASN pTunnel2BgpNeighborIpAddress: default: VPN Tunnel 2 BGP Neighbor IP Address pUseElasticIp: default: Use Elastic IP Address? (true/false) pEipAllocationId: default: Elastic IP Address Allocation ID pLocalBgpAsn: default: Local VPN Gateway's BGP ASN pVpcId: default: VPC ID pVpcCidr: default: VPC CIDR Block pSubnetId: default: Subnet ID for VPN Gateway pInstanceType: default: EC2 Instance Type pAmiId: default: EC2 AMI ID Parameters: pOrg: Type: String Description: Used to qualify resource names Default: example pSystem: Type: String Description: Used to qualify resource names Default: infra pApp: Type: String Description: Used to qualify resource names Default: vpngw pEnvPurpose: Type: String Description: Used to qualify resource names. 10 characters max. AllowedPattern: '^[a-zA-Z0-9-_]{1,10}$' pTunnel1Psk: Description: VPN Tunnel 1 Pre-Shared Key Type: String pTunnel1VgwOutsideIpAddress: Description: VPN Tunnel 1 Virtual Private Gateway Outside IP Address Type: String pTunnel1VgwInsideCidr: Description: VPN Tunnel 1 Virtual Private Gateway Inside CIDR Type: String AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|3[0-8]))$ pTunnel1CgwInsideCidr: Description: VPN Tunnel 1 Customer Gateway Inside CIDR Type: String AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|3[0-8]))$ pTunnel1BgpAsn: Description: VPN Tunnel 1 BGP ASN Type: Number Default: 64512 pTunnel1BgpNeighborIpAddress: Description: VPN Tunnel 1 BGP Neighbor IP Address Type: String pTunnel2Psk: Description: VPN Tunnel 2 Pre-Shared Key Type: String pTunnel2VgwOutsideIpAddress: Description: VPN Tunnel 2 Virtual Private Gateway Outside IP Address Type: String pTunnel2VgwInsideCidr: Description: VPN Tunnel 2 Virtual Private Gateway Inside CIDR Type: String AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|3[0-8]))$ pTunnel2CgwInsideCidr: Description: VPN Tunnel 2 Customer Gateway Inside CIDR Type: String AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|3[0-8]))$ pTunnel2BgpAsn: Description: VPN Tunnel 2 BGP ASN Type: Number Default: 64512 pUseElasticIp: Type: String Description: Whether Elastic IP address is to be used. Default: false AllowedValues: [true, false] pEipAllocationId: Description: Elastic IP Address Alocation ID Type: String pLocalBgpAsn: Description: Local VPN Gateway's BGP ASN Type: Number Default: 65000 pTunnel2BgpNeighborIpAddress: Description: VPN Tunnel 2 BGP Neighbor IP Address Type: String pVpcId: Description: VPC ID Type: AWS::EC2::VPC::Id pVpcCidr: Description: VPC CIDR Block Type: String AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$ pSubnetId: Description: Subnet ID for VPN Gateway Type: AWS::EC2::Subnet::Id pInstanceType: Description: EC2 Instance Type Type: String Default: t3a.micro AllowedValues: - t3a.micro - t3a.small - t3a.medium ConstraintDescription: must be a valid EC2 instance type. pAmiId: Description: EC2 AMI ID Type: 'AWS::SSM::Parameter::Value' Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs' Rules: SubnetsInVPC: Assertions: - Assert: 'Fn::EachMemberIn': - 'Fn::ValueOfAll': - 'AWS::EC2::Subnet::Id' - VpcId - 'Fn::RefAll': 'AWS::EC2::VPC::Id' AssertDescription: All subnets must in the VPC Conditions: cUseElasticIp: !Equals [ !Ref 'pUseElasticIp', true ] Resources: rInstanceSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupName: !Sub '${pSystem}-${pApp}-ec2-${pEnvPurpose}' VpcId: !Ref pVpcId GroupDescription: Allow traffic from other VPN gateway and all locally sourced traffic SecurityGroupIngress: - IpProtocol: udp FromPort: 500 ToPort: 500 CidrIp: !Sub '${pTunnel1VgwOutsideIpAddress}/32' - IpProtocol: udp FromPort: 500 ToPort: 500 CidrIp: !Sub '${pTunnel2VgwOutsideIpAddress}/32' - IpProtocol: udp FromPort: 4500 ToPort: 4500 CidrIp: !Sub '${pTunnel1VgwOutsideIpAddress}/32' - IpProtocol: udp FromPort: 4500 ToPort: 4500 CidrIp: !Sub '${pTunnel2VgwOutsideIpAddress}/32' - IpProtocol: '50' CidrIp: !Sub '${pTunnel1VgwOutsideIpAddress}/32' - IpProtocol: '50' CidrIp: !Sub '${pTunnel2VgwOutsideIpAddress}/32' - IpProtocol: '51' CidrIp: !Sub '${pTunnel1VgwOutsideIpAddress}/32' - IpProtocol: '51' CidrIp: !Sub '${pTunnel2VgwOutsideIpAddress}/32' - IpProtocol: '-1' FromPort: 0 ToPort: 65535 CidrIp: !Ref pVpcCidr rLaunchTemplate: Type: AWS::EC2::LaunchTemplate Properties: LaunchTemplateName: !Sub '${pSystem}-${pApp}-${pEnvPurpose}' LaunchTemplateData: InstanceType: !Ref pInstanceType ImageId: !Ref pAmiId IamInstanceProfile: Arn: !GetAtt rInstanceProfile.Arn NetworkInterfaces: - DeviceIndex: 0 DeleteOnTermination: true Description: !Sub '${pSystem}-${pApp}-${pEnvPurpose}' Groups: - !Ref rInstanceSecurityGroup AssociatePublicIpAddress: !Ref pUseElasticIp UserData: Fn::Base64: !Sub | #!/bin/bash -xe yum install -y aws-cfn-bootstrap /opt/aws/bin/cfn-init -v \ --stack ${AWS::StackName} \ --resource rLaunchTemplate \ --configsets All \ --region ${AWS::Region} /opt/aws/bin/cfn-signal -e $? \ '${rVpnGatewayWaitHandle}' Metadata: AWS::CloudFormation::Init: configSets: All: - 01-ConfigureCloudWatchMetrics - 02-ConfigureCloudWatchLogsAgent - 03-InstallEpel - 04-ConfigureVpnGateway 01-ConfigureCloudWatchMetrics: packages: yum: perl-Switch: [] perl-DateTime: [] perl-Sys-Syslog: [] perl-LWP-Protocol-https: [] perl-Digest-SHA.x86_64: [] sources: /home/ec2-user: >- https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.2.zip files: /home/ec2-user/crontab: content: !Sub | */1 * * * * ~/aws-scripts-mon/mon-put-instance-data.pl --aws-iam-role=${rRole} --mem-used --memory-units=megabytes --mem-util --disk-space-util --disk-space-used --disk-space-avail --disk-path=/ mode: '000600' owner: ec2-user group: ec2-user commands: 01-yum-update: command: yum update -y 02-monitoring-cron: command: >- chmod +x /home/ec2-user/aws-scripts-mon/*.pl && crontab -u ec2-user /home/ec2-user/crontab && rm /home/ec2-user/crontab 02-ConfigureCloudWatchLogsAgent: packages: yum: awslogs: [] files: /etc/awslogs/awslogs.conf: content: !Sub | [general] state_file= /var/awslogs/state/agent-state [/var/log/cloud-init.log] file = /var/log/cloud-init.log log_group_name = ${rCloudWatchLogsAgentGroup} log_stream_name = {instance_id}/cloud-init.log datetime_format = [/var/log/cloud-init-output.log] file = /var/log/cloud-init-output.log log_group_name = ${rCloudWatchLogsAgentGroup} log_stream_name = {instance_id}/cloud-init-output.log datetime_format = [/var/log/cfn-init.log] file = /var/log/cfn-init.log log_group_name = ${rCloudWatchLogsAgentGroup} log_stream_name = {instance_id}/cfn-init.log datetime_format = [/var/log/cfn-wire.log] file = /var/log/cfn-wire.log log_group_name = ${rCloudWatchLogsAgentGroup} log_stream_name = {instance_id}/cfn-wire.log datetime_format = [/var/log/charon.log] file = /var/log/charon.log log_group_name = ${rCloudWatchLogsAgentGroup} log_stream_name = {instance_id}/charon.log datetime_format = [/var/log/quagga/zebra.log] file = /var/log/quagga/zebra.log log_group_name = ${rCloudWatchLogsAgentGroup} log_stream_name = {instance_id}/zebra.log datetime_format = [/var/log/quagga/bgpd.log] file = /var/log/quagga/bgpd.log log_group_name = ${rCloudWatchLogsAgentGroup} log_stream_name = {instance_id}/bgpd.log datetime_format = mode: '000444' owner: root group: root /etc/awslogs/awscli.conf: content: !Sub | [plugins] cwlogs = cwlogs [default] region = ${AWS::Region} mode: '000444' owner: root group: root commands: 01-create-awslogs-state-file: command: mkdir -p /var/awslogs/state 02-enable-awslogsd: command: systemctl enable awslogsd.service 03-start-awslogsd: command: systemctl start awslogsd 03-InstallEpel: commands: 01-install-epel: command: amazon-linux-extras install epel -y 04-ConfigureVpnGateway: packages: yum: strongswan: [] ntp: [] quagga: [] files: /etc/strongswan/strongswan.conf: content: | # strongswan.conf - strongSwan configuration file # # Refer to the strongswan.conf(5) manpage for details # # Configuration changes should be made in the included files charon { plugins { include strongswan.d/charon/*.conf } load_modular = yes filelog { charon { path = /var/log/charon.log time_format = %b %e %T ike_name = yes append = yes } } } mode: '000600' owner: root group: root /etc/strongswan/ipsec.conf: content: !Sub | conn %default leftauth=psk rightauth=psk ike=aes256-sha256-modp2048s256,aes128-sha1-modp1024! ikelifetime=28800s aggressive=no esp=aes128-sha256-modp2048s256,aes128-sha1-modp1024! lifetime=3600s type=tunnel dpddelay=10s dpdtimeout=30s keyexchange=ikev1 rekey=yes reauth=no dpdaction=restart closeaction=restart left=%defaultroute leftsubnet=0.0.0.0/0,::/0 rightsubnet=0.0.0.0/0,::/0 leftupdown=/etc/strongswan/ipsec-vti.sh installpolicy=yes compress=no mobike=no conn AWS-VPC-TUNNEL-1 left=%any right=${pTunnel1VgwOutsideIpAddress} auto=start mark=100 conn AWS-VPC-TUNNEL-2 left=%any right=${pTunnel2VgwOutsideIpAddress} auto=start mark=200 mode: '000600' owner: root group: root /etc/strongswan/ipsec-vti.sh: content: !Sub | #!/bin/bash #@ /etc/strongswan/ipsec-vti.sh (Centos) or /etc/strongswan.d/ipsec-vti.sh (Ubuntu) # AWS VPC Hardware VPN Strongswan updown Script # Usage Instructions: # Add "install_routes = no" to /etc/strongswan/strongswan.d/charon.conf or /etc/strongswan.d/charon.conf # Add "install_virtual_ip = no" to /etc/strongswan/strongswan.d/charon.conf or /etc/strongswan.d/charon.conf # For Ubuntu: Add "leftupdown=/etc/strongswan.d/ipsec-vti.sh" to /etc/ipsec.conf # For RHEL/Centos: Add "leftupdown=/etc/strongswan/ipsec-vti.sh" to /etc/strongswan/ipsec.conf # For RHEL/Centos 6 and below: git clone git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git && cd iproute2 && make && cp ./ip/ip /usr/local/sbin/ip # Adjust the below according to the Generic Gateway Configuration file provided to you by AWS. # Sample: http://docs.aws.amazon.com/AmazonVPC/latest/NetworkAdminGuide/GenericConfig.html IP=$(which ip) IPTABLES=$(which iptables) PLUTO_MARK_OUT_ARR=(${!PLUTO_MARK_OUT//// }) PLUTO_MARK_IN_ARR=(${!PLUTO_MARK_IN//// }) case "$PLUTO_CONNECTION" in AWS-VPC-TUNNEL-1) VTI_INTERFACE=vti1 VTI_LOCALADDR=${pTunnel1CgwInsideCidr} VTI_REMOTEADDR=${pTunnel1VgwInsideCidr} ;; AWS-VPC-TUNNEL-2) VTI_INTERFACE=vti2 VTI_LOCALADDR=${pTunnel2CgwInsideCidr} VTI_REMOTEADDR=${pTunnel2VgwInsideCidr} ;; esac case "${!PLUTO_VERB}" in up-client) #$IP tunnel add ${!VTI_INTERFACE} mode vti local ${!PLUTO_ME} remote ${!PLUTO_PEER} okey ${!PLUTO_MARK_OUT_ARR[0]} ikey ${!PLUTO_MARK_IN_ARR[0]} $IP link add ${!VTI_INTERFACE} type vti local ${!PLUTO_ME} remote ${!PLUTO_PEER} okey ${!PLUTO_MARK_OUT_ARR[0]} ikey ${!PLUTO_MARK_IN_ARR[0]} sysctl -w net.ipv4.conf.${!VTI_INTERFACE}.disable_policy=1 sysctl -w net.ipv4.conf.${!VTI_INTERFACE}.rp_filter=2 || sysctl -w net.ipv4.conf.${!VTI_INTERFACE}.rp_filter=0 $IP addr add ${!VTI_LOCALADDR} remote ${!VTI_REMOTEADDR} dev ${!VTI_INTERFACE} $IP link set ${!VTI_INTERFACE} up mtu 1436 $IPTABLES -t mangle -I FORWARD -o ${!VTI_INTERFACE} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu $IPTABLES -t mangle -I INPUT -p esp -s ${!PLUTO_PEER} -d ${!PLUTO_ME} -j MARK --set-xmark ${!PLUTO_MARK_IN} $IP route flush table 220 #/etc/init.d/bgpd reload || /etc/init.d/quagga force-reload bgpd ;; down-client) #$IP tunnel del ${!VTI_INTERFACE} $IP link del ${!VTI_INTERFACE} $IPTABLES -t mangle -D FORWARD -o ${!VTI_INTERFACE} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu $IPTABLES -t mangle -D INPUT -p esp -s ${!PLUTO_PEER} -d ${!PLUTO_ME} -j MARK --set-xmark ${!PLUTO_MARK_IN} ;; esac mode: '000700' owner: root group: root /etc/strongswan/ipsec.secrets: content: !Sub | ${pTunnel1VgwOutsideIpAddress} : PSK "${pTunnel1Psk}" ${pTunnel2VgwOutsideIpAddress} : PSK "${pTunnel2Psk}" mode: '000600' owner: root group: root /etc/quagga/zebra.conf: content: | hostname {HOSTNAME} password zebra enable password zebra ! log file /var/log/quagga/zebra.log ! ! Configure interfaces interface lo ! Change preferred source ip address of received routes route-map RM_SET_SRC permit 10 set src {PRIVATE_IP} ip protocol bgp route-map RM_SET_SRC ! line vty mode: '000600' owner: quagga group: quagga /etc/quagga/bgpd.conf: content: !Sub | hostname bgpd password zebra enable password zebra ! log file /var/log/quagga/bgpd.log ! debug bgp events debug bgp filters debug bgp fsm debug bgp keepalives debug bgp updates ! router bgp ${pLocalBgpAsn} bgp router-id {PRIVATE_IP} network ${pVpcCidr} neighbor ${pTunnel1BgpNeighborIpAddress} remote-as ${pTunnel1BgpAsn} neighbor ${pTunnel2BgpNeighborIpAddress} remote-as ${pTunnel2BgpAsn} neighbor ${pTunnel2BgpNeighborIpAddress} route-map RM_LOWER_PRIORITY out ! route-map RM_LOWER_PRIORITY permit 10 set as-path prepend ${pLocalBgpAsn} ${pLocalBgpAsn} ${pLocalBgpAsn} ! line vty mode: '000600' owner: quagga group: quagga /etc/sysctl.conf: content: | # sysctl settings are defined through files in # /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/. # # Vendors settings live in /usr/lib/sysctl.d/. # To override a whole file, create a new file with the same in # /etc/sysctl.d/ and put new settings there. To override # only specific settings, add a file with a lexically later # name in /etc/sysctl.d/ and put new settings there. # # For more information, see sysctl.conf(5) and sysctl.d(5). net.ipv4.ip_forward = 1 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.tcp_max_syn_backlog = 1280 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.icmp_ignore_bogus_error_responses = 1 net.ipv4.tcp_syncookies = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.tcp_mtu_probing = 1 mode: '000600' owner: root group: root commands: 00-sed-instance-specific-settings: command: >- ipaddr=$(curl 169.254.169.254/latest/meta-data/local-ipv4) && sed -i -e "s/{PRIVATE_IP}/${ipaddr}/" /etc/quagga/zebra.conf && sed -i -e "s/{PRIVATE_IP}/${ipaddr}/" /etc/quagga/bgpd.conf && hostname=$(curl 169.254.169.254/latest/meta-data/local-hostname) && sed -i -e "s/{HOSTNAME}/${hostname}/" /etc/quagga/zebra.conf 01-load-sysctl-changes: command: sysctl -p /etc/sysctl.conf 02-enable-ip-forwarding: command: >- sysctl -w net.ipv4.ip_forward=1 && sysctl -w net.ipv4.conf.eth0.disable_xfrm=1 && sysctl -w net.ipv4.conf.eth0.disable_policy=1 03-enable-start-ntpd: command: >- systemctl enable ntpd && systemctl start ntpd 04-enable-start-strongswan: command: >- systemctl enable strongswan && systemctl start strongswan 05-enable-start-zebra: command: >- systemctl enable zebra && systemctl start zebra 06-enable-start-bgpd: command: >- systemctl enable bgpd && systemctl start bgpd rVpnGatewayEipAssociation: Type: AWS::EC2::EIPAssociation Condition: cUseElasticIp Properties: AllocationId: !Ref pEipAllocationId InstanceId: !Ref rVpnGateway rVpnGateway: Type: AWS::EC2::Instance Properties: LaunchTemplate: LaunchTemplateId: Ref: rLaunchTemplate Version: Fn::GetAtt: [ rLaunchTemplate, LatestVersionNumber ] NetworkInterfaces: - DeviceIndex: '0' SubnetId: !Ref pSubnetId SourceDestCheck: false Tags: - Key: Name Value: !Sub '${pSystem}-${pApp}-${pEnvPurpose}' rVpnGatewayWaitHandle: Type: AWS::CloudFormation::WaitConditionHandle rVpnGatewayWaitCondition1: Type: AWS::CloudFormation::WaitCondition DependsOn: rVpnGateway Properties: Handle: Ref: rVpnGatewayWaitHandle Timeout: '300' Count: 1 rRole: Type: AWS::IAM::Role Properties: RoleName: !Sub '${pOrg}-${pSystem}-${pApp}-${pEnvPurpose}-svc-cloud-watch-ssm' Path: !Sub '/${pOrg}/${pSystem}/${pApp}/' AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore - arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy rInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: InstanceProfileName: !Sub '${pSystem}-${pApp}-${pEnvPurpose}' Path: !Sub '/${pOrg}/${pSystem}/${pApp}/' Roles: - !Ref rRole rCloudWatchLogsAgentGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub '/${pSystem}/${pApp}/ec2/${pEnvPurpose}' RetentionInDays: 1