# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy of this # software and associated documentation files (the "Software"), to deal in the Software # without restriction, including without limitation the rights to use, copy, modify, # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AWSTemplateFormatVersion: 2010-09-09 Description: >- Running Apache CloudStack on EC2 the Simple Way: This template creates an EC2 instance and security group. In order to connect to the instance, you'll need to add route table entries for the virtual subnet CIDR, using the EC2 instance as the target. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template. ############################################################################### # Metadata ############################################################################### Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: VPC Parameters: - VpcId - Subnet - DnsAddress - AccessLocation - Label: default: EC2 Parameters: - InstanceType - KeyName - RootVolumeSize - Label: default: Virtual Subnet Parameters: - VirtualSubnetIpAddress - VirtualSubnetMask - Label: default: CloudStack Settings Parameters: - CloudStackVersion - CloudStackPublicTrafficCidr - CloudStackPodCidr - CloudStackSharedNetworkCidr - SampleTemplateName - SampleTemplateUrl ############################################################################### # Parameters ############################################################################### Parameters: VpcId: Type: AWS::EC2::VPC::Id Description: >- VpcId of your existing Virtual Private Cloud (VPC). DNS resolution and DNS hostnames must be enabled on the VPC. ConstraintDescription: Must be the VPC Id of an existing Virtual Private Cloud. Subnet: Type: AWS::EC2::Subnet::Id Description: A SubnetId in your Virtual Private Cloud (VPC) ConstraintDescription: >- Must be an existing subnet residing in the selected Virtual Private Cloud. Internet access is required, either via NAT Gateway or other means. DnsAddress: Description: >- The IP address of an existing DNS server that should be used by CloudStack and its VMs. (169.254.169.253 is not allowed because CloudStack reserves link-local addresses for its own use. Try the VPC base address plus two.) Type: String MinLength: 7 MaxLength: 15 AllowedPattern: '(?!169\.254\.)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' ConstraintDescription: Must be a valid IPv4 address the in form x.x.x.x. Must not be in the 169.254.0.0/16 range. AccessLocation: Description: >- The IP address range (in CIDR notation) that can be used to access the CloudStack EC2 instance and VMs. If you're not sure what to put here, try your VPC CIDR. For security reasons, this demo requires a suffix of /16 or greater. After you update the appropriate route tables, two-way communication will be possible between machines in the access location and those in the virtual subnet. When adding routes, use the virtual subnet as the destination, and the CloudStack instance as the target. The EC2 instance will use NAT when forwarding traffic from the virtual subnet to addresses outside of the access location. Type: String MinLength: 9 MaxLength: 18 AllowedPattern: '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/(1[6-9]|2[0-4])' ConstraintDescription: >- Must be a valid IP CIDR range in the form x.x.x.x/x. For security reasons, this demo requires a suffix of /16 or greater. InstanceType: Description: >- The EC2 instance type for the CloudStack host (hypervisor). **WARNING** Research the costs for your region! Metal instances can be very expensive. Type: String Default: c5.metal AllowedValues: - c5.metal - c5d.metal - c5n.metal - c6i.metal - c6id.metal - g4dn.metal - i3.metal - i3en.metal - i4i.metal - m5.metal - m5d.metal - m5dn.metal - m5n.metal - m5zn.metal - m6i.metal - m6id.metal - r5.metal - r5b.metal - r5d.metal - r5dn.metal - r5n.metal - r6i.metal - r6id.metal - z1d.metal ConstraintDescription: must be a valid bare metal x86_64 Nitro instance type. KeyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the instances Type: AWS::EC2::KeyPair::KeyName ConstraintDescription: must be the name of an existing EC2 KeyPair. RootVolumeSize: Description: >- The size of the root volume in GB. Must be at least 10. This space will be used for the operating system, CloudStack's primary and secondary storage, MySQL, log files, etc. Type: Number Default: 100 MinValue: 10 VirtualSubnetIpAddress: Description: The IP address to be assigned to the CloudStack host in the virtual subnet Type: String MinLength: 7 MaxLength: 15 Default: 10.100.0.1 AllowedPattern: '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' ConstraintDescription: Must be a valid IPv4 address in the form x.x.x.x. VirtualSubnetMask: Description: The virtual subnet's mask Type: String MinLength: 7 MaxLength: 15 Default: 255.255.0.0 AllowedPattern: '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' ConstraintDescription: Must be a valid IPv4 subnet mask in the form x.x.x.x. CloudStackVersion: Description: The version of CloudStack to install. Must be >= 4.16. Only 4.17 has been tested. Type: String Default: 4.17 AllowedPattern: '4\.(1[6-9]|[2-9][0-9])' ConstraintDescription: Must be a 4.x version, and >= 4.16 CloudStackPublicTrafficCidr: Description: The IP address range (in CIDR notation) in the virtual subnet for system VMs. Type: String Default: 10.100.1.0/24 MinLength: 9 MaxLength: 18 AllowedPattern: '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2}' ConstraintDescription: Must be a valid IP CIDR range in the form x.x.x.x/x. CloudStackPodCidr: Description: The IP address range (in CIDR notation) in the virtual subnet for the management network (control plane). Type: String Default: 10.100.2.0/24 MinLength: 9 MaxLength: 18 AllowedPattern: '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2}' ConstraintDescription: Must be a valid IP CIDR range in the form x.x.x.x/x. CloudStackSharedNetworkCidr: Description: The IP address range (in CIDR notation) in the virtual subnet for user-created VMs. Type: String Default: 10.100.128.0/24 MinLength: 9 MaxLength: 18 AllowedPattern: '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2}' ConstraintDescription: Must be a valid IP CIDR range in the form x.x.x.x/x. SampleTemplateName: Description: The name of a KVM template (in QCOW2 format) to register with CloudStack (optional) Type: String SampleTemplateUrl: Description: The URL of a KVM template (in QCOW2 format) to register with CloudStack (optional) Type: String AllowedPattern: '(?i)(^$|https?://.+\.qcow2)' ConstraintDescription: Must start with http:// or https://, and end with .qcow2 ############################################################################### # Resources ############################################################################### Resources: CloudStackSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: !Ref VpcId GroupDescription: >- Enable access to the CloudStack UI, and to any services that may be offered by the VMs SecurityGroupIngress: - IpProtocol: icmp FromPort: 8 ToPort: -1 CidrIp: !Ref AccessLocation - IpProtocol: tcp FromPort: 0 ToPort: 65535 CidrIp: !Ref AccessLocation - IpProtocol: udp FromPort: 0 ToPort: 65535 CidrIp: !Ref AccessLocation CloudStackInstance: Type: AWS::EC2::Instance Metadata: AWS::CloudFormation::Init: configSets: cloudstack_install: - get_scripts - install - signal_completion get_scripts: files: /bootstrap/common.sh: source: https://raw.githubusercontent.com/aws-samples/amazon-ec2-running-apache-cloudstack/main/common.sh mode: 600 owner: root group: root /bootstrap/install_cloudstack_on_ec2.sh: source: https://raw.githubusercontent.com/aws-samples/amazon-ec2-running-apache-cloudstack/main/install_cloudstack_on_ec2.sh mode: 700 owner: root group: root /bootstrap/configure_cloudstack_demo.sh: source: https://raw.githubusercontent.com/aws-samples/amazon-ec2-running-apache-cloudstack/main/configure_cloudstack_demo.sh mode: 700 owner: root group: root install: commands: 01_install_cloudstack: command: - '/bootstrap/install_cloudstack_on_ec2.sh' - '--cloudstack-version' - !Ref CloudStackVersion - '--dns-ip' - !Ref DnsAddress - '--limit-log-files' - '--virtual-host-ip' - !Ref VirtualSubnetIpAddress - '--virtual-netmask' - !Ref VirtualSubnetMask # NAT is needed for CloudStack to download VM templatesbefore the user has a chance to # update the route tables to provide Internet access to the virtual subnet. - '--nat' - '--nat-exception' - !Ref AccessLocation cwd: /bootstrap 02_configure_cloudstack: command: - '/bootstrap/configure_cloudstack_demo.sh' - '--dns-ip' - !Ref DnsAddress - '--gateway-ip' - !Ref VirtualSubnetIpAddress - '--host-ip' - !Ref VirtualSubnetIpAddress - '--netmask' - !Ref VirtualSubnetMask - '--pod-cidr' - !Ref CloudStackPodCidr - '--public-traffic-cidr' - !Ref CloudStackPublicTrafficCidr - '--shared-network-cidr' - !Ref CloudStackSharedNetworkCidr - '--primary-storage-url' - !Sub nfs://${VirtualSubnetIpAddress}/export/primary - '--secondary-storage-url' - !Sub nfs://${VirtualSubnetIpAddress}/export/secondary - '--template-name' - !Ref SampleTemplateName - '--template-url' - !Ref SampleTemplateUrl cwd: /bootstrap signal_completion: commands: # Add a temporary route so cfn-signal can succeed. 01_add_route: command: 'route add 169.254.169.254/32 dev eth0' 02_signal: command: - '/usr/local/bin/cfn-signal' - '-e' - '0' - '--stack' - !Ref AWS::StackName - '--resource' - 'CloudStackInstance' - '--region' - !Ref AWS::Region # Delete the temporary route so CloudStack can use link-local addresses for its own needs. 03_delete_route: command: 'route delete 169.254.169.254/32 dev eth0' Properties: # Use x86_64 CentOS 7 from https://aws.amazon.com/marketplace/pp/B08KYKK42V ImageId: 'resolve:ssm:/aws/service/marketplace/prod-a77hqdkwpdk3o/latest' InstanceType: !Ref InstanceType KeyName: !Ref KeyName SourceDestCheck: false NetworkInterfaces: - AssociatePublicIpAddress: false DeviceIndex: 0 GroupSet: - !Ref CloudStackSecurityGroup SubnetId: !Ref Subnet UserData: !Base64 Fn::Join: - '' - - | #!/bin/bash -xe - | yum -y install python3 - | python3 -m easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-py3-latest.tar.gz - | - '/usr/local/bin/cfn-init -v ' - ' --stack ' - !Ref AWS::StackName - ' --resource CloudStackInstance ' - ' --configsets cloudstack_install ' - ' --region ' - !Ref AWS::Region - |+ BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeType: gp2 VolumeSize: !Ref RootVolumeSize DeleteOnTermination: true Encrypted: true Tags: - Key: Name Value: !Ref AWS::StackName CreationPolicy: ResourceSignal: Timeout: PT30M Outputs: InstanceId: Value: !Ref CloudStackInstance Description: The EC2 instance ID CloudStackURL: Value: !Sub http://${VirtualSubnetIpAddress}:8080/client/