├── .gitignore ├── images ├── launchstack.png └── Perforce-servers-architecture.png ├── CODE_OF_CONDUCT.md ├── LICENSE ├── CONTRIBUTING.md ├── README.md └── templates ├── PerforceVPCTemplate.yaml ├── PerforceTemplateMain.yaml └── PerforceServerSetupTemplate.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /images/launchstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-perforce/HEAD/images/launchstack.png -------------------------------------------------------------------------------- /images/Perforce-servers-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-perforce/HEAD/images/Perforce-servers-architecture.png -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Building Perforce Helix Core on the AWS Cloud 2 | 3 | These AWS CloudFormation templates included with this sample deploy Perforce Helix Core on the AWS Cloud. 4 | 5 | Perforce is a proprietary version control system that features fast synchronized operation. It’s used mainly in development environments and is particularly popular in the game industry. 6 | 7 | Perforce and AWS also offer a free tier, [Perforce Helix Core Studio Pack for AWS](https://www.perforce.com/vcs/aws-studio-pack), which allows customers to start running Perforce on AWS. 8 | 9 | The templates automate either of the following: 10 | 11 | * Deploy a single Perforce master server into a single availability zone of a new VPC 12 | * Deploy Perforce master server and replica server for redundancy into different availability zones of a new VPC 13 | 14 | You can also use the AWS CloudFormation templates as a starting point for your own implementation. 15 | 16 | ![Perforce-servers-architecture](/images/Perforce-servers-architecture.png) 17 | 18 | ## License 19 | 20 | This library is licensed under the MIT-0 License. See the LICENSE file. 21 | 22 | The AWS CloudFormation templates download and setup Perforce Helix Core on EC2 instances during the process. 23 | Helix Core is a proprietary software and is subject to the terms and conditions of Perforce. Please refer to EULA in the following page for details. 24 | 25 | [Perforce Terms of Use](https://www.perforce.com/terms-use) 26 | 27 | 28 | ## Deployment 29 | 1. Sign in to the AWS console and click on Launch Stack below. This launches a CloudFormation stack in your AWS account. By default, the stack is launched in the us-west-2 (Oregon) region. If you want to launch it in a different region, change the region from the pull-down menu in the upper right corner of the management console. 30 | 31 | [![Launch Stack](/images/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/create/template?stackName=AWSPerforceTest&templateURL=https://gametech-cfn-templates-public.s3.amazonaws.com/aws-perforce/templates/PerforceTemplateMain.yaml) 32 | 33 | 2. On the **Specify template** page, keep the default setting for the template URL, and then choose Next. 34 | 35 | 3. On the **Specify stack details** page, change the stack name if needed. By default, the stack name is **AWSPerforceTest**. Review the parameters for the template. Especially provide the following items for the parameters that require input. For all other parameters, review the default settings and customize them as necessary. When you finish reviewing and customizing the parameters, choose Next. 36 | 37 | * In **VPC Network Configuration**, **Permitted IP range** is configured to restrict access to the Perforce Server based on the source IPs. The default settings allow all IP addresses (0.0.0.0/0), but allowing only limited IP addresses is recommended for security reasons. 38 | 39 | * **Perforce Server Configuration** allows you to specify the EC2 instance type of the Perforce Server. By default, **c5.4xlarge** is recommended for use in the production environment. However, it is not always appropriate to use for testing purposes, so choose **t3.nano** or **t3.micro** for tests, which have lower hourly rates. Please note that the t3 family is intended for use in the test environment and should not be used in the production environment. 40 | 41 | * Select the **SSH Key** you use to log in to the instance from Key Pair Name. If you have not created an SSH key in advance, create a key pair in your preferred region. 42 | 43 | * If you scroll down the Parameters screen, you will see the **EBS volume configuration** you want to set to the server, but do nothing and leave it as the default. However, some parameters have larger volume sizes by default, so you may set smaller sizes if you prefer to save costs. (For testing purposes, for example, 500GiB, the lowest volume size of st1 should be sufficient for Depot, and 8 GiB of storage should be sufficient for the others. ) 44 | 45 | * The setting **Enable Replica** is asking if you want to create a Perforce Replica Server. The default value is set to **No**, allowing to build only a Perforce Master Server. If you also need to build a Replica server, change this setting from the pull-down to **Yes**. 46 | (The additional procedure is requred to complete the replica setup.) 47 | 48 | 4. Click on Next to navigate to the **Configure stack options** page. No additional configuration is required here. (Add tags if necessary. ) 49 | 50 | 5. Click on Next to navigate to review page. Scroll down to the bottom, and you will see check boxes in the **Capabilities** section. Check them all. Ensure to check all the check boxes. Click on **Create Stack**, and then the building process starts. It will take about 5-10 minutes to complete. When **CREATE_COMPLETE** is displayed, the building process is complete. 51 | -------------------------------------------------------------------------------- /templates/PerforceVPCTemplate.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: "Perforce-server-vpc-template" 3 | 4 | Parameters: 5 | EnableReplica: 6 | Type: String 7 | Default: "No" 8 | AllowedValues: 9 | - "Yes" 10 | - "No" 11 | Description: "If you build Perforce Replica Server, select Yes. Replica Server will be the same setting as Master server." 12 | AccessCIDR: 13 | AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) 14 | ConstraintDescription: "must be a valid IP CIDR range of the form x.x.x.x/x." 15 | Description: "The IP address range that can be used to access to the EC2 instance" 16 | MaxLength: '18' 17 | MinLength: '9' 18 | Default: '0.0.0.0/0' 19 | Type: String 20 | 21 | Conditions: 22 | CreateReplicaServer: !Equals [ !Ref EnableReplica, "Yes" ] 23 | 24 | Resources: 25 | PerforceVPC: 26 | Type: AWS::EC2::VPC 27 | Properties: 28 | CidrBlock: 10.0.0.0/16 29 | InstanceTenancy: default 30 | EnableDnsSupport: 'true' 31 | EnableDnsHostnames: 'false' 32 | Tags: 33 | - Key: Name 34 | Value: Perforce 35 | PerforcePublicSubnetMaster: 36 | Type: AWS::EC2::Subnet 37 | Properties: 38 | CidrBlock: 10.0.0.0/24 39 | AvailabilityZone: !Select 40 | - 0 41 | - Fn::GetAZs: !Ref 'AWS::Region' 42 | VpcId: 43 | Ref: PerforceVPC 44 | Tags: 45 | - Key: Name 46 | Value: Perforce-Public-Subnet-Master 47 | PerforcePublicSubnetReplica: 48 | Type: AWS::EC2::Subnet 49 | Condition: CreateReplicaServer 50 | Properties: 51 | CidrBlock: 10.0.1.0/24 52 | AvailabilityZone: !Select 53 | - 1 54 | - Fn::GetAZs: !Ref 'AWS::Region' 55 | VpcId: 56 | Ref: PerforceVPC 57 | Tags: 58 | - Key: Name 59 | Value: Perforce-Public-Subnet-Replica 60 | PerforceIGW: 61 | Type: AWS::EC2::InternetGateway 62 | Properties: 63 | Tags: 64 | - Key: Name 65 | Value: Public-Perforce 66 | dopt06d06862: 67 | Type: AWS::EC2::DHCPOptions 68 | Properties: 69 | DomainName: !Sub ${AWS::Region}.compute.internal 70 | DomainNameServers: 71 | - AmazonProvidedDNS 72 | PerforceNACL: 73 | Type: AWS::EC2::NetworkAcl 74 | Properties: 75 | VpcId: 76 | Ref: PerforceVPC 77 | PerforceRouteTable: 78 | Type: AWS::EC2::RouteTable 79 | Properties: 80 | VpcId: 81 | Ref: PerforceVPC 82 | sgPerforceSG: 83 | Type: AWS::EC2::SecurityGroup 84 | Properties: 85 | GroupDescription: This security group is for Perforce. 86 | VpcId: 87 | Ref: PerforceVPC 88 | acl1: 89 | Type: AWS::EC2::NetworkAclEntry 90 | Properties: 91 | CidrBlock: 0.0.0.0/0 92 | Egress: 'true' 93 | Protocol: '-1' 94 | RuleAction: allow 95 | RuleNumber: '100' 96 | NetworkAclId: 97 | Ref: PerforceNACL 98 | acl2: 99 | Type: AWS::EC2::NetworkAclEntry 100 | Properties: 101 | CidrBlock: 0.0.0.0/0 102 | Protocol: '-1' 103 | RuleAction: allow 104 | RuleNumber: '100' 105 | NetworkAclId: 106 | Ref: PerforceNACL 107 | subnetacl1: 108 | Type: AWS::EC2::SubnetNetworkAclAssociation 109 | Properties: 110 | NetworkAclId: 111 | Ref: PerforceNACL 112 | SubnetId: 113 | Ref: PerforcePublicSubnetMaster 114 | subnetacl2: 115 | Type: AWS::EC2::SubnetNetworkAclAssociation 116 | Condition: CreateReplicaServer 117 | Properties: 118 | NetworkAclId: 119 | Ref: PerforceNACL 120 | SubnetId: 121 | Ref: PerforcePublicSubnetReplica 122 | gw1: 123 | Type: AWS::EC2::VPCGatewayAttachment 124 | Properties: 125 | VpcId: 126 | Ref: PerforceVPC 127 | InternetGatewayId: 128 | Ref: PerforceIGW 129 | route1: 130 | Type: AWS::EC2::Route 131 | Properties: 132 | DestinationCidrBlock: 0.0.0.0/0 133 | RouteTableId: 134 | Ref: PerforceRouteTable 135 | GatewayId: 136 | Ref: PerforceIGW 137 | DependsOn: gw1 138 | subnetrtbassoc1: 139 | Type: AWS::EC2::SubnetRouteTableAssociation 140 | Properties: 141 | RouteTableId: 142 | Ref: PerforceRouteTable 143 | SubnetId: 144 | Ref: PerforcePublicSubnetMaster 145 | subnetrtbassoc2: 146 | Type: AWS::EC2::SubnetRouteTableAssociation 147 | Condition: CreateReplicaServer 148 | Properties: 149 | RouteTableId: !Ref PerforceRouteTable 150 | SubnetId: !Ref PerforcePublicSubnetReplica 151 | dchpassoc1: 152 | Type: AWS::EC2::VPCDHCPOptionsAssociation 153 | Properties: 154 | VpcId: !Ref PerforceVPC 155 | DhcpOptionsId: !Ref dopt06d06862 156 | ingress1: 157 | Type: AWS::EC2::SecurityGroupIngress 158 | Properties: 159 | GroupId: !Ref sgPerforceSG 160 | IpProtocol: tcp 161 | FromPort: '22' 162 | ToPort: '22' 163 | CidrIp: !Ref AccessCIDR 164 | ingress2: 165 | Type: AWS::EC2::SecurityGroupIngress 166 | Properties: 167 | GroupId: !Ref sgPerforceSG 168 | IpProtocol: tcp 169 | FromPort: '443' 170 | ToPort: '443' 171 | CidrIp: !Ref AccessCIDR 172 | ingress3: 173 | Type: AWS::EC2::SecurityGroupIngress 174 | Properties: 175 | GroupId: !Ref sgPerforceSG 176 | IpProtocol: tcp 177 | FromPort: '1666' 178 | ToPort: '1666' 179 | CidrIp: !Ref AccessCIDR 180 | ingress4: 181 | Type: 'AWS::EC2::SecurityGroupIngress' 182 | Properties: 183 | GroupId: !Ref sgPerforceSG 184 | IpProtocol: tcp 185 | FromPort: '22' 186 | ToPort: '22' 187 | SourceSecurityGroupId: !Ref sgPerforceSG 188 | ingress5: 189 | Type: 'AWS::EC2::SecurityGroupIngress' 190 | Properties: 191 | GroupId: !Ref sgPerforceSG 192 | IpProtocol: tcp 193 | FromPort: '443' 194 | ToPort: '443' 195 | SourceSecurityGroupId: !Ref sgPerforceSG 196 | ingress6: 197 | Type: 'AWS::EC2::SecurityGroupIngress' 198 | Properties: 199 | GroupId: !Ref sgPerforceSG 200 | IpProtocol: tcp 201 | FromPort: '1666' 202 | ToPort: '1666' 203 | SourceSecurityGroupId: !Ref sgPerforceSG 204 | egress1: 205 | Type: AWS::EC2::SecurityGroupEgress 206 | Properties: 207 | GroupId: !Ref sgPerforceSG 208 | IpProtocol: '-1' 209 | CidrIp: 0.0.0.0/0 210 | # Setting IAM Role for EC2 instance 211 | EC2Role: 212 | Type: AWS::IAM::Role 213 | Properties: 214 | Description: "EC2 service role for S3 full access" 215 | AssumeRolePolicyDocument: 216 | Statement: 217 | - Effect: Allow 218 | Principal: 219 | Service: 220 | - "ec2.amazonaws.com" 221 | Action: 222 | - "sts:AssumeRole" 223 | Path: / 224 | ManagedPolicyArns: 225 | - arn:aws:iam::aws:policy/AmazonS3FullAccess 226 | RoleName: PerforceEC2RoleForS3Access 227 | EC2Profile: 228 | Type: AWS::IAM::InstanceProfile 229 | Properties: 230 | Path: "/" 231 | Roles: 232 | - !Ref EC2Role 233 | InstanceProfileName: EC2S3AcessProfile 234 | 235 | Outputs: 236 | PerforceMasterSubnetId: 237 | Description: "Newly created Public Subnet ID for Master" 238 | Value: !Ref PerforcePublicSubnetMaster 239 | PerforceReplicaSubnetId: 240 | Condition: CreateReplicaServer 241 | Description: "Newly created Public Subnet ID for Replica" 242 | Value: !Ref PerforcePublicSubnetReplica 243 | PerforceSecurityGroupId: 244 | Description: "Newly created sercurity group ID for Perforce" 245 | Value: !Ref sgPerforceSG 246 | PerforceVPCGatewaySettingID: 247 | Description: "VPC gateway setting for Perforce" 248 | Value: !Ref gw1 249 | EC2ProfileID: 250 | Description: "EC2 profile setting for Perforce" 251 | Value: !Ref EC2Profile 252 | -------------------------------------------------------------------------------- /templates/PerforceTemplateMain.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: "Perforce-server-main-template" 3 | Metadata: 4 | AWS::CloudFormation::Interface: 5 | ParameterGroups: 6 | - Label: 7 | default: ' VPC Network Configuration' 8 | Parameters: 9 | - AccessCIDR 10 | - Label: 11 | default: "Perforce Server Configuration" 12 | Parameters: 13 | - InstanceType 14 | - KeyPairName 15 | - DepotVolumeType 16 | - DepotVolumeSize 17 | - LogVolumeSize 18 | - MetadataVolumeType 19 | - MetadataVolumeSize 20 | - MetadataProvisionedIops 21 | - LatestAmiId 22 | - EnableReplica 23 | - Label: 24 | default: "AWS CloudFormation Template Source Configuration" 25 | Parameters: 26 | - QSS3BucketName 27 | - QSS3BucketRegion 28 | - QSS3KeyPrefix 29 | ParameterLabels: 30 | AccessCIDR: 31 | default: Permitted IP range 32 | InstanceType: 33 | default: "Instance Type" 34 | KeyPairName: 35 | default: "Key Pair Name" 36 | DepotVolumeType: 37 | default: "Volume Type for Depot" 38 | DepotVolumeSize: 39 | default: "Volume Size for Depot" 40 | LogVolumeSize: 41 | default: "Volume Size for Log" 42 | MetadataVolumeType: 43 | default: "Volume Type for Metadata" 44 | MetadataVolumeSize: 45 | default: "Volume Size for Metadata" 46 | MetadataProvisionedIops: 47 | default: "Provisioned IOPS for Metadata Volume" 48 | LatestAmiId: 49 | default: "Latest AMI ID for Amazon Linux2" 50 | EnableReplica: 51 | default: "Enable Replica" 52 | QSS3BucketName: 53 | default: "Template S3 Bucket Name" 54 | QSS3BucketRegion: 55 | default: "Template S3 bucket region" 56 | QSS3KeyPrefix: 57 | default: "Template S3 Key Prefix" 58 | 59 | Parameters: 60 | AccessCIDR: 61 | AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) 62 | ConstraintDescription: "must be a valid IP CIDR range of the form x.x.x.x/x." 63 | Description: "The IP address range that can be used to access to the EC2 instance" 64 | MaxLength: '18' 65 | MinLength: '9' 66 | Default: '0.0.0.0/0' 67 | Type: String 68 | InstanceType: 69 | Type: String 70 | Default: c5.4xlarge 71 | AllowedValues: 72 | - t3.nano 73 | - t3.micro 74 | - t3.small 75 | - t3.medium 76 | - c5.large 77 | - c5.xlarge 78 | - c5.2xlarge 79 | - c5.4xlarge 80 | - c5.9xlarge 81 | - r5.large 82 | - r5.xlarge 83 | - r5.2xlarge 84 | - r5.4xlarge 85 | - r5.8xlarge 86 | - m5.large 87 | - m5.xlarge 88 | - m5.2xlarge 89 | - m5.4xlarge 90 | - m5.8xlarge 91 | Description: "Select Perforce server EC2 instance type. Default is c5.4xlarge." 92 | KeyPairName: 93 | ConstraintDescription: "You must specify the name of an existing EC2 KeyPair." 94 | Description: "Public/private key pairs allow you to securely connect to your instance after it launches" 95 | Type: AWS::EC2::KeyPair::KeyName 96 | LatestAmiId: 97 | Type: AWS::SSM::Parameter::Value 98 | Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 99 | EnableReplica: 100 | Type: String 101 | Default: "No" 102 | AllowedValues: 103 | - "Yes" 104 | - "No" 105 | Description: "If you build Perforce Replica Server, select Yes. Replica Server will be the same setting as Master server." 106 | DepotVolumeType: 107 | Type: String 108 | Default: st1 109 | AllowedValues: 110 | - st1 111 | - gp2 112 | Description: "Select either ST1 or GP2." 113 | DepotVolumeSize: 114 | Type: String 115 | Default: '1024' 116 | Description: "The size of the EBS volume attached for Depot." 117 | LogVolumeSize: 118 | Type: String 119 | Default: '128' 120 | Description: "The size of the EBS volume attached for Log." 121 | MetadataVolumeType: 122 | Type: String 123 | Default: gp2 124 | AllowedValues: 125 | - gp2 126 | - io1 127 | Description: "Select either GP2 or IO1." 128 | MetadataVolumeSize: 129 | Type: String 130 | Default: '64' 131 | Description: "The size of the EBS volume attached for Metadata." 132 | MetadataProvisionedIops: 133 | ConstraintDescription: "Range is 100 to 64000 for Provisioned IOPS SSD volumes." 134 | Description: "Set the provisioned IOPs between 100 and 64000. Only set if you are choosing io1 for your metadata volume type." 135 | Type: "String" 136 | QSS3BucketName: 137 | AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ 138 | ConstraintDescription: | 139 | Template bucket name can include numbers, lowercase 140 | letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). 141 | Default: gametech-cfn-templates-public 142 | Description: | 143 | S3 bucket name for the template assets. Template bucket name 144 | can include numbers, lowercase letters, uppercase letters, and hyphens (-). 145 | It cannot start or end with a hyphen (-). 146 | Type: String 147 | QSS3BucketRegion: 148 | Default: 'us-east-1' 149 | Description: 'The AWS Region where the template S3 bucket (QSS3BucketName) is hosted. When using your own bucket, you must specify this value.' 150 | Type: String 151 | QSS3KeyPrefix: 152 | AllowedPattern: ^[0-9a-zA-Z-]+(/[0-9a-zA-Z-]+)*/ 153 | ConstraintDescription: | 154 | Template key prefix can include numbers, lowercase letters, 155 | uppercase letters, hyphens (-), and forward slash (/). It cannot start with 156 | forward slash (/) because it is automatically added. 157 | Default: aws-perforce/ 158 | Description: | 159 | S3 key prefix for the template assets. Template key prefix can include 160 | numbers, lowercase letters, uppercase letters, hyphens (-), and forward slash 161 | (/). It cannot start with forward slash (/) because it is automatically added. 162 | Type: String 163 | 164 | Conditions: 165 | CreateReplicaServer: !Equals [ !Ref EnableReplica, "Yes" ] 166 | UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'gametech-cfn-templates-public'] 167 | GovCloudCondition: !Equals [!Ref 'AWS::Region', us-gov-west-1] 168 | 169 | Resources: 170 | PerforceVPCStack: 171 | Type: AWS::CloudFormation::Stack 172 | Properties: 173 | TemplateURL: !Sub "https://${QSS3BucketName}.s3.${QSS3BucketRegion}.amazonaws.com/${QSS3KeyPrefix}templates/PerforceVPCTemplate.yaml" 174 | Parameters: 175 | EnableReplica: !Ref EnableReplica 176 | AccessCIDR: !Ref AccessCIDR 177 | 178 | # Create Perforce master server 179 | PerforceMasterServerInstance: 180 | Type: AWS::CloudFormation::Stack 181 | Properties: 182 | TemplateURL: !Sub "https://${QSS3BucketName}.s3.${QSS3BucketRegion}.amazonaws.com/${QSS3KeyPrefix}templates/PerforceServerSetupTemplate.yaml" 183 | Parameters: 184 | PerforceAZ: !Select 185 | - 0 186 | - Fn::GetAZs: !Ref 'AWS::Region' 187 | LatestAmiId: !Ref LatestAmiId 188 | InstanceType: !Ref InstanceType 189 | KeyPairName: !Ref KeyPairName 190 | ServerName: "p4-awsnva-01" 191 | ServerDescription: "Master/commit server. The master.1 is the SDP instance name, a data set identifier." 192 | ServerID: "master.1" 193 | DepotVolumeType: !Ref DepotVolumeType 194 | DepotVolumeSize: !Ref DepotVolumeSize 195 | LogVolumeSize: !Ref LogVolumeSize 196 | MetadataVolumeType: !Ref MetadataVolumeType 197 | MetadataVolumeSize: !Ref MetadataVolumeSize 198 | MetadataProvisionedIops: !Ref MetadataProvisionedIops 199 | SubnetId: !GetAtt PerforceVPCStack.Outputs.PerforceMasterSubnetId 200 | PrivateIpAddress: 10.0.0.63 201 | PerforceSecurityGroup: !GetAtt PerforceVPCStack.Outputs.PerforceSecurityGroupId 202 | gw1: !GetAtt PerforceVPCStack.Outputs.PerforceVPCGatewaySettingID 203 | EC2Profile: !GetAtt PerforceVPCStack.Outputs.EC2ProfileID 204 | # Create Perforce replica server if needed 205 | PerforceReplicaServerInstance: 206 | Type: AWS::CloudFormation::Stack 207 | Condition: CreateReplicaServer 208 | Properties: 209 | TemplateURL: !Sub "https://${QSS3BucketName}.s3.${QSS3BucketRegion}.amazonaws.com/${QSS3KeyPrefix}templates/PerforceServerSetupTemplate.yaml" 210 | Parameters: 211 | PerforceAZ: !Select 212 | - 1 213 | - Fn::GetAZs: !Ref 'AWS::Region' 214 | LatestAmiId: !Ref LatestAmiId 215 | InstanceType: !Ref InstanceType 216 | KeyPairName: !Ref KeyPairName 217 | ServerName: "p4-awsnva-02" 218 | ServerDescription: "Replica server. The p4d-ha-awsnva is the SDP instance name, a data set identifier." 219 | ServerID: "p4d-ha-awsnva" 220 | DepotVolumeType: !Ref DepotVolumeType 221 | DepotVolumeSize: !Ref DepotVolumeSize 222 | LogVolumeSize: !Ref LogVolumeSize 223 | MetadataVolumeType: !Ref MetadataVolumeType 224 | MetadataVolumeSize: !Ref MetadataVolumeSize 225 | MetadataProvisionedIops: !Ref MetadataProvisionedIops 226 | SubnetId: !GetAtt PerforceVPCStack.Outputs.PerforceReplicaSubnetId 227 | PrivateIpAddress: 10.0.1.63 228 | PerforceSecurityGroup: !GetAtt PerforceVPCStack.Outputs.PerforceSecurityGroupId 229 | gw1: !GetAtt PerforceVPCStack.Outputs.PerforceVPCGatewaySettingID 230 | EC2Profile: !GetAtt PerforceVPCStack.Outputs.EC2ProfileID 231 | 232 | Outputs: 233 | PerforceMasterEIP: 234 | Description: Elasic IP Adress attached to Perforce Master server 235 | Value: !GetAtt PerforceMasterServerInstance.Outputs.PerforceEIP 236 | PerforceReplicaEIP: 237 | Condition: CreateReplicaServer 238 | Description: Elasic IP Adress attached to Perforce Replica server 239 | Value: !GetAtt PerforceReplicaServerInstance.Outputs.PerforceEIP 240 | PerforceMasterInstanceId: 241 | Description: InstanceId of the newly created EC2 instance 242 | Value: !GetAtt PerforceMasterServerInstance.Outputs.EC2InstanceId 243 | PerforceReplicaInstanceId: 244 | Condition: CreateReplicaServer 245 | Description: InstanceId of the newly created EC2 instance 246 | Value: !GetAtt PerforceReplicaServerInstance.Outputs.EC2InstanceId 247 | -------------------------------------------------------------------------------- /templates/PerforceServerSetupTemplate.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | Description: "Create Perforce Servers" 3 | 4 | Parameters: 5 | InstanceType: 6 | Type: String 7 | Default: c5.4xlarge 8 | AllowedValues: 9 | - t3.nano 10 | - t3.micro 11 | - t3.small 12 | - t3.medium 13 | - c5.large 14 | - c5.xlarge 15 | - c5.2xlarge 16 | - c5.4xlarge 17 | - c5.9xlarge 18 | - r5.large 19 | - r5.xlarge 20 | - r5.2xlarge 21 | - r5.4xlarge 22 | - r5.8xlarge 23 | - m5.large 24 | - m5.xlarge 25 | - m5.2xlarge 26 | - m5.4xlarge 27 | - m5.8xlarge 28 | Description: "Select Perforce server EC2 instance type. Default is c5.4xlarge." 29 | KeyPairName: 30 | Description: "Public/private key pairs allow you to securely connect to your instance after it launches" 31 | Type: AWS::EC2::KeyPair::KeyName 32 | LatestAmiId: 33 | Type: "String" 34 | PerforceAZ: 35 | Type: "String" 36 | ServerName: 37 | Type: "String" 38 | ServerDescription: 39 | Type: "String" 40 | ServerID: 41 | Type: "String" 42 | SubnetId: 43 | Type: "String" 44 | PrivateIpAddress: 45 | Type: "String" 46 | PerforceSecurityGroup: 47 | Type: "String" 48 | gw1: 49 | Type: "String" 50 | DepotVolumeType: 51 | Type: String 52 | Default: st1 53 | AllowedValues: 54 | - st1 55 | - gp2 56 | Description: "Select either ST1 or GP2." 57 | DepotVolumeSize: 58 | Type: String 59 | Default: '1024' 60 | Description: "The size of the EBS volume attached for Depot." 61 | LogVolumeSize: 62 | Type: String 63 | Default: '128' 64 | Description: "The size of the EBS volume attached for Log." 65 | MetadataVolumeType: 66 | Type: String 67 | Default: gp2 68 | AllowedValues: 69 | - gp2 70 | - io1 71 | Description: "Select either GP2 or IO1." 72 | MetadataVolumeSize: 73 | Type: String 74 | Default: '64' 75 | Description: "The size of the EBS volume attached for Metadata." 76 | MetadataProvisionedIops: 77 | Type: "String" 78 | ConstraintDescription: "Range is 100 to 64000 for Provisioned IOPS SSD volumes." 79 | Description: "Set the provisioned IOPs between 100 and 64000. Only set if you are choosing io1 for your metadata volume type." 80 | EC2Profile: 81 | Type: "String" 82 | Description: "EC2 proifile setting for IAM role" 83 | 84 | Resources: 85 | PerforceEIP: 86 | Type: AWS::EC2::EIP 87 | Properties: 88 | Domain: vpc 89 | # Setup EBS volumes 90 | VolumeHxlogs: 91 | Type: AWS::EC2::Volume 92 | Properties: 93 | AvailabilityZone: !Ref PerforceAZ 94 | Size: 95 | Ref: LogVolumeSize 96 | VolumeType: gp2 97 | Tags: 98 | - Key: Name 99 | Value: !Sub ${ServerName}-hxlogs 100 | - Key: ServerID 101 | Value: !Ref ServerID 102 | VolumeHxdepots: 103 | Type: AWS::EC2::Volume 104 | Properties: 105 | AvailabilityZone: !Ref PerforceAZ 106 | Encrypted: true 107 | Size: 108 | Ref: DepotVolumeSize 109 | VolumeType: 110 | Ref: DepotVolumeType 111 | Tags: 112 | - Key: ServerID 113 | Value: !Ref ServerID 114 | - Key: Name 115 | Value: !Sub ${ServerName}-hxdepots 116 | VolumeHxmetadata: 117 | Type: AWS::EC2::Volume 118 | Properties: 119 | AvailabilityZone: !Ref PerforceAZ 120 | Size: 121 | Ref: MetadataVolumeSize 122 | VolumeType: 123 | Ref: MetadataVolumeType 124 | Iops: 125 | Ref: MetadataProvisionedIops 126 | Tags: 127 | - Key: Name 128 | Value: !Sub ${ServerName}-hxmetadata 129 | - Key: ServerID 130 | Value: !Ref ServerID 131 | # setup EC2 instance & perforce 132 | PerforceServerInstance: 133 | Type: AWS::EC2::Instance 134 | Properties: 135 | AvailabilityZone: !Ref PerforceAZ 136 | DisableApiTermination: 'false' 137 | InstanceInitiatedShutdownBehavior: stop 138 | EbsOptimized: 'true' 139 | ImageId: !Ref LatestAmiId 140 | InstanceType: !Ref InstanceType 141 | KeyName: !Ref KeyPairName 142 | Monitoring: 'true' 143 | IamInstanceProfile: !Ref EC2Profile 144 | Tags: 145 | - Key: Name 146 | Value: !Ref ServerName 147 | - Key: Description 148 | Value: !Ref ServerDescription 149 | - Key: ServerID 150 | Value: !Ref ServerID 151 | Volumes: 152 | - Device: /dev/sdb 153 | VolumeId: !Ref VolumeHxdepots 154 | - Device: /dev/sdc 155 | VolumeId: !Ref VolumeHxlogs 156 | - Device: /dev/sdd 157 | VolumeId: !Ref VolumeHxmetadata 158 | NetworkInterfaces: 159 | - DeleteOnTermination: 'true' 160 | Description: Primary network interface 161 | DeviceIndex: 0 162 | SubnetId: !Ref SubnetId 163 | PrivateIpAddresses: 164 | - PrivateIpAddress: !Ref PrivateIpAddress 165 | Primary: 'true' 166 | GroupSet: 167 | - !Ref PerforceSecurityGroup 168 | UserData: !Base64 169 | Fn::Sub: | 170 | #!/bin/bash 171 | hostname ${ServerID} 172 | 173 | # Install packages 174 | yum -y update 175 | 176 | yum -y install aws-cfn-bootstrap 177 | # Install the files and packages from the metadata 178 | # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-init.html 179 | /opt/aws/bin/cfn-init -v --configsets default --stack ${AWS::StackName} --resource PerforceServerInstance --region ${AWS::Region} 180 | # Signal the status from cfn-init 181 | # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-signal.html 182 | /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource PerforceServerInstance --region ${AWS::Region} 183 | 184 | Metadata: 185 | # https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-init.html 186 | AWS::CloudFormation::Init: 187 | configSets: 188 | default: 189 | - "01_config_setup_volumes" 190 | - "02_config_setup_yum_repo" 191 | - "03_config_helix-p4d" 192 | - "04_config_install_sdp" 193 | - "05_config_start_helix-p4d" 194 | 01_config_setup_volumes: 195 | commands: 196 | # Mount hxdepots 197 | 01_setup_hxdepots: 198 | command: "mkfs -t xfs /dev/sdb && mkdir /hxdepots && mount /dev/sdb /hxdepots" 199 | ignoreErrors: false 200 | # Mount hxlogs 201 | 02_setup_hxlogs: 202 | command: "mkfs -t xfs /dev/sdc && mkdir /hxlogs && mount /dev/sdc /hxlogs" 203 | ignoreErrors: false 204 | # Mount hxmetadata 205 | 03_setup_hxmetadata: 206 | command: "mkfs -t xfs /dev/sdd && mkdir /hxmetadata && mount /dev/sdd /hxmetadata" 207 | ignoreErrors: false 208 | # Configure /etc/fstab 209 | 04_add_config_to_fstab: 210 | command: blkid /dev/sdb | awk -v OFS=" " '{print $2,"/hxdepots","xfs","defaults,nofail","0","2"}' >> /etc/fstab 211 | ignoreErrors: false 212 | 05_add_config_to_fstab: 213 | command: blkid /dev/sdc | awk -v OFS=" " '{print $2,"/hxlogs","xfs","defaults,nofail","0","2"}' >> /etc/fstab 214 | ignoreErrors: false 215 | 06_add_config_to_fstab: 216 | command: blkid /dev/sdd | awk -v OFS=" " '{print $2,"/hxmetadata","xfs","defaults,nofail","0","2"}' >> /etc/fstab 217 | ignoreErrors: false 218 | 02_config_setup_yum_repo: 219 | # Add yum repository 220 | files: 221 | /etc/yum.repos.d/perforce.repo: 222 | content: !Sub | 223 | [perforce] 224 | name=Perforce 225 | baseurl=http://package.perforce.com/yum/rhel/7/x86_64/ 226 | enabled=1 227 | gpgcheck=1 228 | mode: "000644" 229 | owner: "root" 230 | group: "root" 231 | commands: 232 | 01_import_pubkey: 233 | command: "rpm --import https://package.perforce.com/perforce.pubkey" 234 | ignoreErrors: false 235 | 03_config_helix-p4d: 236 | packages: 237 | yum: 238 | helix-p4d: [] 239 | commands: 240 | 01_adduser_p4admin: 241 | command: "adduser -g perforce -G adm,wheel p4admin" 242 | ignoreErrors: false 243 | 02_mkdir_p4admin_dir: 244 | command: "mkdir /home/p4admin/.ssh" 245 | ignoreErrors: false 246 | 03_cp_key: 247 | command: "cp /home/ec2-user/.ssh/authorized_keys /home/p4admin/.ssh" 248 | ignoreErrors: false 249 | 04_chown: 250 | command: "chown p4admin:perforce --recursive /home/p4admin/.ssh" 251 | ignoreErrors: false 252 | 05_chmod: 253 | command: "chmod 700 /home/p4admin/.ssh" 254 | ignoreErrors: false 255 | 06_chmod: 256 | command: "chmod 600 /home/p4admin/.ssh/authorized_keys" 257 | ignoreErrors: false 258 | 07_allow_p4admin_sudo: 259 | command: "echo 'p4admin ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers" 260 | ignoreErrors: false 261 | 04_config_install_sdp: 262 | sources: 263 | /tmp: "https://swarm.workshop.perforce.com/downloads/guest/perforce_software/sdp/downloads/sdp.Unix.tgz?v=%2314" 264 | commands: 265 | 01_mv_sdp: 266 | command: "mv /tmp/sdp /hxdepots" 267 | ignoreErrors: false 268 | 02_backup_config: 269 | command: "cp /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg.bak" 270 | ignoreErrors: false 271 | 03_rewrite_config: 272 | command: "sudo sed -i -e 's/DB1=.*/DB1=hxmetadata/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 273 | ignoreErrors: false 274 | 04_rewrite_config: 275 | command: "sed -i -e 's/DB2=.*/DB2=hxmetadata/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 276 | ignoreErrors: false 277 | 05_rewrite_config: 278 | command: "sed -i -e 's/DD=.*/DD=hxdepots/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 279 | ignoreErrors: false 280 | 06_rewrite_config: 281 | command: "sed -i -e 's/LG=.*/LG=hxlogs/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 282 | ignoreErrors: false 283 | 07_rewrite_config: 284 | command: "sed -i -e 's/OSUSER=.*/OSUSER=p4admin/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 285 | ignoreErrors: false 286 | 08_rewrite_config: 287 | command: "sed -i -e 's/OSGROUP=.*/OSGROUP=perforce/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 288 | ignoreErrors: false 289 | 09_rewrite_config: 290 | command: "sed -i -e 's/CASE_SENSITIVE=.*/CASE_SENSITIVE=0/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 291 | ignoreErrors: false 292 | 10_rewrite_config: 293 | command: "sed -i -e 's/MAILHOST=.*/MAILHOST=localhost/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 294 | ignoreErrors: false 295 | 11_rewrite_config: 296 | command: "sed -i -e 's/SSL_PREFIX=.*/SSL_PREFIX=/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 297 | ignoreErrors: false 298 | 12_rewrite_config: 299 | command: !Sub "sed -i -e 's/P4DNSNAME=.*/P4DNSNAME=ip-10-0-0-63.${AWS::Region}.compute.internal/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 300 | ignoreErrors: false 301 | 13_rewrite_config: 302 | command: "sed -i -e 's/COMPLAINFROM_DOMAIN=.*/COMPLAINFROM_DOMAIN=amazonaws.com/g' /hxdepots/sdp/Server/Unix/setup/mkdirs.cfg" 303 | ignoreErrors: false 304 | 14_create_symlink: 305 | command: "ln -s /opt/perforce/bin/p4 /hxdepots/sdp/Server/Unix/p4/common/bin/p4" 306 | ignoreErrors: false 307 | 15_create_symlink: 308 | command: "ln -s /opt/perforce/sbin/p4d /hxdepots/sdp/Server/Unix/p4/common/bin/p4d" 309 | ignoreErrors: false 310 | 16_setup_sdp: 311 | command: "/hxdepots/sdp/Server/Unix/setup/mkdirs.sh 1" 312 | ignoreErrors: false 313 | 05_config_start_helix-p4d: 314 | files: 315 | /etc/systemd/system/p4d_1.service: 316 | content: !Sub | 317 | [Unit] 318 | Description=Helix Server Instance 1 319 | Documentation=http://www.perforce.com/perforce/doc.current/manuals/p4sag/index.html 320 | Requires=network.target network-online.target 321 | After=network.target network-online.target 322 | 323 | [Service] 324 | Type=forking 325 | TimeoutStartSec=60s 326 | TimeoutStopSec=60s 327 | ExecStart=/p4/1/bin/p4d_1_init start 328 | ExecStop=/p4/1/bin/p4d_1_init stop 329 | User=p4admin 330 | 331 | [Install] 332 | WantedBy=multi-user.target 333 | mode: "000400" 334 | owner: "p4admin" 335 | group: "perforce" 336 | commands: 337 | 01_enable_daemon: 338 | command: "systemctl enable p4d_1" 339 | ignoreErrors: false 340 | 02_start_daemon: 341 | command: "systemctl start p4d_1" 342 | ignoreErrors: false 343 | 03_set_serverID: 344 | command: !Sub "echo ${ServerID} > /p4/1/root/server.id" 345 | ignoreErrors: false 346 | 04_configure_server: 347 | command: "/hxdepots/sdp/Server/setup/configure_new_server.sh 1" 348 | ignoreErrors: false 349 | 350 | assocEIP: 351 | Type: AWS::EC2::EIPAssociation 352 | Properties: 353 | AllocationId: 354 | Fn::GetAtt: 355 | - PerforceEIP 356 | - AllocationId 357 | InstanceId: !Ref PerforceServerInstance 358 | 359 | Outputs: 360 | EC2InstanceId: 361 | Description: InstanceId of the newly created EC2 instance 362 | Value: !Ref PerforceServerInstance 363 | PerforceEIP: 364 | Description: Elasic IP Adress attached to Perforce server 365 | Value: !Ref PerforceEIP 366 | --------------------------------------------------------------------------------