From 5d2fb7a6599801124222dce60455f1ac84c069e0 Mon Sep 17 00:00:00 2001 From: Vinay Aggarwal Date: Mon, 18 Nov 2019 16:54:25 -0800 Subject: [PATCH] added Cloud Formation templates for ECS and EKS --- CloudFormation-JCR-ECS/.gitmodules | 12 + CloudFormation-JCR-ECS/LICENSE.txt | 202 +++++ CloudFormation-JCR-ECS/Makefile | 34 + CloudFormation-JCR-ECS/README.md | 0 .../ci/jfrog-new-vpc-jcr6-ecs.json | 74 ++ CloudFormation-JCR-ECS/ci/taskcat.yml | 14 + .../scripts/roles/artifactory/README.md | 72 ++ .../roles/artifactory/defaults/main.yml | 50 ++ .../files/inactiveServerCleaner.groovy | 46 ++ .../artifactory/files/installer-info.json | 7 + .../roles/artifactory/files/nginx.conf | 37 + .../roles/artifactory/handlers/main.yml | 13 + .../scripts/roles/artifactory/meta/main.yml | 53 ++ .../roles/artifactory/tasks/configure.yml | 100 +++ .../roles/artifactory/tasks/configure_ecs.yml | 83 +++ .../roles/artifactory/tasks/install.yml | 18 + .../scripts/roles/artifactory/tasks/main.yml | 17 + .../roles/artifactory/tasks/nginx-setup.yml | 26 + .../templates/artifactory.cluster.license.j2 | 18 + .../artifactory/templates/artifactory.conf.j2 | 33 + .../artifactory/templates/binarystore.xml.j2 | 38 + .../artifactory/templates/certificate.key.j2 | 1 + .../artifactory/templates/certificate.pem.j2 | 2 + .../artifactory/templates/db.properties.j2 | 5 + .../templates/ha-node.properties.j2 | 9 + .../roles/artifactory/templates/master.key.j2 | 1 + .../scripts/site-artifactory.yml | 5 + .../jfrog-jcr6-ecs-ec2.template.yaml | 399 ++++++++++ .../jfrog-jcr6-ecs-existing-vpc.template.yaml | 704 ++++++++++++++++++ .../jfrog-jcr6-ecs-master.template.yaml | 541 ++++++++++++++ .../templates/jfrog-jcr6-ecs.template.yaml | 183 +++++ CloudFormation-JCR-EKS/.gitmodules | 12 + CloudFormation-JCR-EKS/LICENSE.txt | 202 +++++ CloudFormation-JCR-EKS/Makefile | 34 + CloudFormation-JCR-EKS/README.md | 0 .../ci/jfrog-new-vpc-jcr6-eks.json | 70 ++ CloudFormation-JCR-EKS/ci/taskcat.yml | 13 + ...jfrog-jcr6-eks-core-workload.template.yaml | 301 ++++++++ .../jfrog-jcr6-eks-existing-vpc.template.yaml | 663 +++++++++++++++++ .../jfrog-jcr6-eks-master.template.yaml | 598 +++++++++++++++ 40 files changed, 4690 insertions(+) create mode 100644 CloudFormation-JCR-ECS/.gitmodules create mode 100644 CloudFormation-JCR-ECS/LICENSE.txt create mode 100644 CloudFormation-JCR-ECS/Makefile create mode 100644 CloudFormation-JCR-ECS/README.md create mode 100755 CloudFormation-JCR-ECS/ci/jfrog-new-vpc-jcr6-ecs.json create mode 100755 CloudFormation-JCR-ECS/ci/taskcat.yml create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/README.md create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/defaults/main.yml create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/files/inactiveServerCleaner.groovy create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/files/installer-info.json create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/files/nginx.conf create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/handlers/main.yml create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/meta/main.yml create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure.yml create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure_ecs.yml create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/install.yml create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/main.yml create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/nginx-setup.yml create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.cluster.license.j2 create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.conf.j2 create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/binarystore.xml.j2 create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.key.j2 create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.pem.j2 create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/db.properties.j2 create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/ha-node.properties.j2 create mode 100644 CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/master.key.j2 create mode 100644 CloudFormation-JCR-ECS/scripts/site-artifactory.yml create mode 100755 CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-ec2.template.yaml create mode 100755 CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-existing-vpc.template.yaml create mode 100755 CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-master.template.yaml create mode 100644 CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs.template.yaml create mode 100644 CloudFormation-JCR-EKS/.gitmodules create mode 100644 CloudFormation-JCR-EKS/LICENSE.txt create mode 100644 CloudFormation-JCR-EKS/Makefile create mode 100644 CloudFormation-JCR-EKS/README.md create mode 100755 CloudFormation-JCR-EKS/ci/jfrog-new-vpc-jcr6-eks.json create mode 100755 CloudFormation-JCR-EKS/ci/taskcat.yml create mode 100755 CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-core-workload.template.yaml create mode 100755 CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-existing-vpc.template.yaml create mode 100755 CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-master.template.yaml diff --git a/CloudFormation-JCR-ECS/.gitmodules b/CloudFormation-JCR-ECS/.gitmodules new file mode 100644 index 0000000..940bc00 --- /dev/null +++ b/CloudFormation-JCR-ECS/.gitmodules @@ -0,0 +1,12 @@ +[submodule "submodules/quickstart-aws-vpc"] + path = submodules/quickstart-aws-vpc + url = https://github.com/aws-quickstart/quickstart-aws-vpc.git + branch = master +[submodule "submodules/quickstart-linux-bastion"] + path = submodules/quickstart-linux-bastion + url = https://github.com/aws-quickstart/quickstart-linux-bastion.git + branch = master +[submodule "submodules/quickstart-amazon-eks"] + path = submodules/quickstart-amazon-eks + url = https://github.com/aws-quickstart/quickstart-amazon-eks.git + branch = master diff --git a/CloudFormation-JCR-ECS/LICENSE.txt b/CloudFormation-JCR-ECS/LICENSE.txt new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/CloudFormation-JCR-ECS/LICENSE.txt @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/CloudFormation-JCR-ECS/Makefile b/CloudFormation-JCR-ECS/Makefile new file mode 100644 index 0000000..cc28cac --- /dev/null +++ b/CloudFormation-JCR-ECS/Makefile @@ -0,0 +1,34 @@ +.PHONY: help run submodules + +submodules: + git submodule init + git submodule update + cd submodules/quickstart-linux-bastion && git submodule init && git submodule update + cd submodules/quickstart-amazon-eks && git submodule init && git submodule update + +help: + @echo "make test : executes taskcat" + +create: + aws cloudformation create-stack --stack-name test --template-body file://$(pwd)/templates/jfrog-artifactory-ec2-new-vpc.template --parameters $(cat .ignore/params) --capabilities CAPABILITY_IAM + +delete: + aws cloudformation delete-stack --stack-name test + +.ONESHELL: +test: lint submodules + cd .. && pwd && taskcat -c theflash/ci/config.yml -n + +lint: + time taskcat -l -c ci/config.yml + +public_repo: + taskcat -c theflash/ci/config.yml -u + #https://taskcat-tag-quickstart-jfrog-artifactory-c2fa9d34.s3-us-west-2.amazonaws.com/quickstart-jfrog-artifactory/templates/jfrog-artifactory-ec2-master.template + #curl https://taskcat-tag-quickstart-jfrog-artifactory-7008506c.s3-us-west-2.amazonaws.com/quickstart-jfrog-artifactory/templates/jfrog-artifactory-ec2-master.template + +get_public_dns: + aws elb describe-load-balancers | jq '.LoadBalancerDescriptions[]| .CanonicalHostedZoneName' + +get_bastion_ip: + aws ec2 describe-instances | jq '.[] | select(.[].Instances[].Tags[].Value == "LinuxBastion") ' diff --git a/CloudFormation-JCR-ECS/README.md b/CloudFormation-JCR-ECS/README.md new file mode 100644 index 0000000..e69de29 diff --git a/CloudFormation-JCR-ECS/ci/jfrog-new-vpc-jcr6-ecs.json b/CloudFormation-JCR-ECS/ci/jfrog-new-vpc-jcr6-ecs.json new file mode 100755 index 0000000..6c484e3 --- /dev/null +++ b/CloudFormation-JCR-ECS/ci/jfrog-new-vpc-jcr6-ecs.json @@ -0,0 +1,74 @@ +[ + { + "ParameterKey": "KeyPairName", + "ParameterValue": "$[taskcat_getkeypair]" + }, + { + "ParameterKey": "RemoteAccessCIDR", + "ParameterValue": "10.0.0.0/16" + }, + { + "ParameterKey": "AccessCIDR", + "ParameterValue": "10.0.0.0/16" + }, + { + "ParameterKey": "AvailabilityZones", + "ParameterValue": "$[taskcat_genaz_2]" + }, + { + "ParameterKey": "DatabasePassword", + "ParameterValue": "$[taskcat_genpass_8A]" + }, + { + "ParameterKey": "QSS3BucketName", + "ParameterValue": "$[taskcat_autobucket]" + }, + { + "ParameterKey": "QSS3KeyPrefix", + "ParameterValue": "quickstart-jfrog-artifactory/" + }, + { + "ParameterKey": "SMLicensesName", + "ParameterValue": "jfrog-artifactory" + }, + { + "ParameterKey": "DatabaseInstance", + "ParameterValue": "db.m4.large" + }, + { + "ParameterKey": "ArtifactoryVersion", + "ParameterValue": "6.15.0" + }, + { + "ParameterKey": "NumberOfSecondary", + "ParameterValue": "2" + }, + { + "ParameterKey": "ArtifactoryServerName", + "ParameterValue": "taskcat" + }, + { + "ParameterKey": "AnsibleVaultPass", + "ParameterValue": "$[taskcat_genpass_8A]" + }, + { + "ParameterKey": "MasterKey", + "ParameterValue": "1ce2be4490ca2c662cb79636cf9b7b8e" + }, + { + "ParameterKey": "Certificate", + "ParameterValue": "-----BEGIN CERTIFICATE-----\nMIIFaDCCA1ACCQD45dB5tZFvCDANBgkqhkiG9w0BAQsFADB2MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCVN1bm55dmFsZTEOMAwGA1UECgwFSkZy\nb2cxFDASBgNVBAsMC0FydGlmYWN0b3J5MSAwHgYDVQQDDBdhcnRpZmFjdG9yeS5s\nb2NhbGRvbWFpbjAeFw0xOTA3MjMyMzE4MjVaFw0yMDA3MjIyMzE4MjVaMHYxCzAJ\nBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2YWxlMQ4wDAYD\nVQQKDAVKRnJvZzEUMBIGA1UECwwLQXJ0aWZhY3RvcnkxIDAeBgNVBAMMF2FydGlm\nYWN0b3J5LmxvY2FsZG9tYWluMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\nAgEA0b3OgTFKkNbXXHzPv3l9IqX7fFZcfS2ZMD4mBuNlGQ6kyyraeoKKiVdkOgQV\n/dwDxLeW6y+637J2KBiZTccHUS8/eC5ky9E6ECeFToCYsucUKRiWo9Uss6XS1N+Q\nKQHktCVYy+KFDkJIVEL6LFbUMLz0k1jOhI/FRveT8LQ9cZsfy8KIrCF92ErcdPSL\n02KO6RgaBjxRFtAw2ZdO07O9kcKBC5BpJdrEnJHalVJsJbZOqIuNjyKKp/8s9TtW\nEYhXAbz05RrdQ97Cse1a/rHR5EWL+ITRw3Q/mQUv/ilSrSxb+chtgGb0qdP7aV0h\nLOuxttQFFU2o62LHqnda6dWljxKpSYUz47ugCK0M4T2bRhy7lUgmZ3PcfZYLE2ue\nh1qIJfkDfi1WpbptJAs4MbgfTvF2FCAsh8tyFnl+TA5QBWLRcOF9y1qUAATa1JKX\nzKGf/5hExBRpuq371j4SLAb5qXYUuQqZiCe3O6qTx2Wo/jAOPV49wfK9D9fW5qmq\nND1Rpp8sKjlb2ixm7dhCWyWV+iGHpzX5tjBW35rikAisUoap47I1fNzYMiSTvbhv\n2+by2YY8jsiYRCRIAKzRbgOgDOXnYVtWFpLgUldMqWqo+X3LztYE8CxD0CQK5u12\nGxM5ztXKEaitCqUSjY34Gl4owukA9tzGnu09OuAYGkxVBO0CAwEAATANBgkqhkiG\n9w0BAQsFAAOCAgEATH4kyuKvZtq32b3I7yZ27Xp2yaxABs17g0jAzkv7o9GILo+3\ncVAJS2warQti+c+A2edjqEc97JXb6ul7/SHs7B9B0P4BZSUsI0byuPlQ45Kht891\njz3SF1o6jpKTniQPqsulMMshmYB6oY6CIyvKpaMaG3DypEXFmwEU7CdWr7oVISkn\npU6N6fI+V94Wzd1yHL8Jm/ixP4lqBAZqDhxNRq/Vok94wu2jvWwPIn2M+9myAiOs\nTSpcqLg8Vn70XkK5uuN1UXYU5QDo78GEZpOj7YfCxVjB43Ct/sEiu3iB0GzyEvq6\njlv07H9PyLjYeM7CuhZdgULBqEWbqNhO5XL/QJMYG06kXkT3GiWFP8pjnQRcJM4Z\nqQv8fOTDTuX5GumXKctXJwc7y9uywoIPwffEKlGuofWhihy8r/YXu2BgShDF3zYV\n1RAHVcWtPT5IqejpRZX5LdL4Hr2eCeUkcVCo7qqYLEwxFnQNG1nMrJJ2ewnlzPac\nJNNPRXgTDF3OkbON+3Wn/H0ndqIoqapHXSlkR54Stsk9yjHuaJ9TCANw2mxMDzf0\nRGw9ecirjpzQdP9jT/zK9X4kqFc0T3P6qN3X3s/OPPbroassRk/eqI/oMS6lNcQm\ny+SvRUrdtzKgmAfVE5yMLTVG0cZM4gWJ35DZHHqWnrbFEg7C0NLzoYc6yeQ=\n-----END CERTIFICATE-----" + }, + { + "ParameterKey": "CertificateKey", + "ParameterValue": "-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDRvc6BMUqQ1tdc\nfM+/eX0ipft8Vlx9LZkwPiYG42UZDqTLKtp6goqJV2Q6BBX93APEt5brL7rfsnYo\nGJlNxwdRLz94LmTL0ToQJ4VOgJiy5xQpGJaj1SyzpdLU35ApAeS0JVjL4oUOQkhU\nQvosVtQwvPSTWM6Ej8VG95PwtD1xmx/LwoisIX3YStx09IvTYo7pGBoGPFEW0DDZ\nl07Ts72RwoELkGkl2sSckdqVUmwltk6oi42PIoqn/yz1O1YRiFcBvPTlGt1D3sKx\n7Vr+sdHkRYv4hNHDdD+ZBS/+KVKtLFv5yG2AZvSp0/tpXSEs67G21AUVTajrYseq\nd1rp1aWPEqlJhTPju6AIrQzhPZtGHLuVSCZnc9x9lgsTa56HWogl+QN+LValum0k\nCzgxuB9O8XYUICyHy3IWeX5MDlAFYtFw4X3LWpQABNrUkpfMoZ//mETEFGm6rfvW\nPhIsBvmpdhS5CpmIJ7c7qpPHZaj+MA49Xj3B8r0P19bmqao0PVGmnywqOVvaLGbt\n2EJbJZX6IYenNfm2MFbfmuKQCKxShqnjsjV83NgyJJO9uG/b5vLZhjyOyJhEJEgA\nrNFuA6AM5edhW1YWkuBSV0ypaqj5fcvO1gTwLEPQJArm7XYbEznO1coRqK0KpRKN\njfgaXijC6QD23Mae7T064BgaTFUE7QIDAQABAoICAAgKDnBFQ2Zp1bdl0VC1h2Zc\nllcduE3UAZsnxq1c6fMb7JUc/2LSvhyljOHsZitk04AmyVIacj9Ax+ahir7Acjda\naERjAtoNGvyjhyiLJU82LD+nAZ8l/KCmKn6eUxg/SlTdWZn3BMKXJ86TAqPQcDGu\nDHHZZZEPMbCWrMT9I53HJGDbBAIVBo3T0L9q4DEqBfBJTDYQ+cq2EClG826J5SpB\nGlEnJ+Cbkg2uSYKPtjV712f+cV6bJFVsIn0D2Tiy0SLv6zMc5H5Fe5D2WBaLGlB1\nmffcn22udwGWgVBspQ6eNKhOVmQljhs0VN6lAzCFmDo5xjga0e6zypNuH732wnG3\nrOoIs6Qo5FQT4fSRSdSANlWJ8cF1OPL7ll0CN1BGfNa304s/C+qNO9SgMn6gmp3G\nuXYSgILp5UraRvn/KYXXVf/IRYrg6bnJ1TcuKCWJPjtibFLmIZutPkOTNF3YSW4s\nUOfLFK8Ky4r0/H6Nzt1r/f9qPHqVG7ILPWP1fwpcq06Tb6wvrJ1xkW9f3JTiWLMi\njkDiuQTmDf1JOk/TslZ3Mj6JDYFdHgT3lZdSNHiRuGgQ278ax/waSRn5W0LXr5b5\ntdHOBqLKnq7l96Hj0IArcrgh1ocJw4pP9JFWGDV2zfG+HzTf6QGmWj6j1Vf/91VN\n75tJmgKjScdU/DX+hTQBAoIBAQDy1YVc5Xwr+JzBV+xMorzVdaZ9Fwpycoy7OPy2\nNjFk1XD/cSDDK7aTDd9v8HF8Kmw4kVtngIkP/kdY4Gdu1oP22f2wkKjXGFQaRWPl\nNNEDhC+f7tjvGbF702jhB0kFdn3f7fEWyr4j8FP4xUqOczF2tzPgKeTkfz+ckQ0m\nDgmjm3vcPb+ZDLDE7fBw0On/qZr9dCH0oBwl7CMWmKggzYQEKNBbJowBwIlwTmL6\nI8Xzj7CAcV9sIVboJb7jNQPOCzHJA9bTGf5LMbD6X6D6Avlvd1J74/fFWkLME6CI\n0mlF5aOW2qKMo57DtnnEEKCL/6DXPfRvX6CuwbHqS5SIbwnxAoIBAQDdHPfDcpjU\n51KgFe4WoygNGVI604Aqv4ZnumJ4oshS71KqQidXgGBch9fDUad1txbDkeOHFW4u\nYwT67VsHeP7jbCA1Rn7MY8DASlSdJkZ7e4trUh1xfYH5tJK3i5hXMPu221sc7l5z\nNTKlohn00tIjy0adehk5oIyr1w1l9DtX6TMK2uNa7Z79mYFZLhrWRX6a93M4MA+J\nTq0bKF8j+x8RG2VZF6mom4XkHLOhYC9osG4xbj8AbhKBt9XrUcu+TT9Ct/kE7b54\ncvWtyf19cwviApebfQIn31pwieUaSncztSHdARCgVETP1334yOtrgKWb3CifaQHH\n0N+BqsrJR469AoIBAHAufAHCcm7N13zqZVuyApKKW3OGZWkhyinj1btHpeHzSNR5\nKq1/UET3L7XC2mqGHqCzZgqWsrsUuVkxshbeOvCbHDupWJalwpSwYcnNcJGzS10T\nNlye/gM6U0VB3FYNu3Drt2jUGKr5p5FRc3QDe2JgmDKCqB93OafWysA90+4lMj84\nt365AiC321AC81cMv3E/aUBdhyNtx3f05hbhWo+hW0AAusVEcTnUvJzaUeSHCP8N\nYQvPCxsL9Pd50lwph8JZZ7D2XSfXuO6xpuhY32rDMPPTCO+/FwS4PH141vFXeQ+D\nyXw3Sm0Xq4EMPV7vpRpKoNWi09Rn3w1iBShSQ8ECggEBAK7l3flEaS1m+I1WK2jO\nj7ykvc14RJYLvwXHgWKI6EnpsgqonzPwgMhQT1PY/8v2EdSKTl4ojmm0u1i8bNeh\nVoSPn35kj6GeefXgFcPkZbYBCEvQvSdrLmdU9QSoL80wGrsOEaj1x9H7T1+CtGNa\nawwTG30u+ksB+qNmTNvLbzFfbZd1gocHFE7moFDpTiMU/0sW1pWoNnHWwMiNi4wL\ndAx1DhqFxBZxRlwkc9X/HiECBXemC8GMT6k5v8UOg0m5EoP0v82tPI9L55cbAh67\n5LdWc5NzM0RUwNXpzUWZh2ZoLSwCTqNzZKa+fo9OZiE3tkdtwtgtGFJ0noaTkSnb\nJ0UCggEAWh58mtJ9TdAZdtU7kkx1/3c91hxl+up8PTSS6BdFa8DXxt9iQq4r914c\nVbfdnzKH7K245alH2aOcdw/TrK0ulQOazGGX2E6pWJV/ndxaUM4beUDUYbTVec3O\niVFWQT/Kp4WQktHQIu0w2fZElgOo30X3eTFEx0bvAm9Or2PiR34JAB5yerrEuFWq\n+Y3oZVb1tzJgLrVqAE6ct/TwkzhLaehlzPFNQb1u5POe3aUHjr5gsZDkqZua3Ys2\nQhArEEmrhEqRBACPWKWb6fSc+ajYlhltLg2g3EMqL4arW/3hgI2KS0vdiPtMRDvQ\n2YpoPnf204ak0AcDNZX257FnjRltUg==\n-----END PRIVATE KEY-----" + }, + { + "ParameterKey": "CertificateDomain", + "ParameterValue": "localdomain" + }, + { + "ParameterKey": "ArtifactoryServerName", + "ParameterValue": "artifactory" + } +] diff --git a/CloudFormation-JCR-ECS/ci/taskcat.yml b/CloudFormation-JCR-ECS/ci/taskcat.yml new file mode 100755 index 0000000..76cd97e --- /dev/null +++ b/CloudFormation-JCR-ECS/ci/taskcat.yml @@ -0,0 +1,14 @@ +global: + marketplace-ami: false + owner: quickstart-eng@amazon.com + qsname: quickstart-jfrog-artifactory + regions: + - us-west-2 + reporting: true + +tests: + jfrog-artifactory-jcr6-ecs: + parameter_input: jfrog-new-vpc-jcr6-ecs.json + template_file: jfrog-jcr6-ecs-master.template.yaml + regions: + - us-west-2 \ No newline at end of file diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/README.md b/CloudFormation-JCR-ECS/scripts/roles/artifactory/README.md new file mode 100644 index 0000000..4ce5870 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/README.md @@ -0,0 +1,72 @@ +Artifactory Master +========= + +A configuration for Artifactory through Cloud Formation. This assumes it will be tied to an AutoScale group, the +environment will have 2 boot groups. 1 with `art_primary=True` and the other `art_primary=False`. Note: The MasterKey +must match in both boot groups or they will not connect. + +Requirements +------------ + +This role is dependent on specific inputs, but does not require any other roles. + +Role Variables +-------------- + +artifactory_licesnes is expected as a list of Artifactory licesnse. +artifactory_server_name is the DNS name of the Artifactory instance. +certificate_domain: Domain name for the DNS name of the Artifactory instance. +s3_endpoint: S3 URL endpoint for backend storage. +s3_access_key: S3 Access key for the S3 Endpoint + Bucket. +s3_access_secret_key: S3 Secret key for the S3 Endpoint + Bucket. +s3_bucket: S3 bucket for backend storage. +certificate_key: Private Certificate Key used for NGINX to terminate SSL +certificate: Certificate used by NGINX to terminate SSL +db_type: Currently only MySQL is supported. +db_ipaddr: MySQL endpoint for the DB connection. +db_name: Name of the Database. +db_user: User with write/read permission on the `db_name` +db_password: Password for the `db_user` +art_primary: True or False (Very important that only one node is art_primary=True) +artifactory_keystore_pass: Java Keystore new Password +master_key: Master Cluster key to join the Artifactory cluster. +artifactory_version: Version of Artifactory to install. + +Dependencies +------------ + +None + +Example Playbook +---------------- + +```yaml +- import_playbook: site-artifactory.yml + vars: + artifactory_licenses: ${ArtifactoryLicense} + artifactory_server_name: ${ArtifactoryServerName} + certificate_domain: ${CertificateDomain} + s3_endpoint: s3.${AWS::Region}.amazonaws.com + s3_access_key: ${ArtifactoryIAMAcessKey} + s3_access_secret_key: ${SecretAccessKey} + s3_bucket: ${ArtifactoryS3Bucket} + certificate_key: ${CertificateKey} + certificate: ${Certificate} + db_type: ${DBType} + db_ipaddr: ${ArtifactoryDBEndpointAddress} + db_name: ${DatabaseName} + db_user: ${DatabaseUser} + db_password: ${DatabasePassword} + art_primary: ${ArtifactoryPrimary} + artifactory_keystore_pass: ${KeystorePassword} + master_key: ${MasterKey} + artifactory_version: ${ArtifactoryVersion} +``` + +License +------- + +BSD + +Author Information +------------------ diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/defaults/main.yml b/CloudFormation-JCR-ECS/scripts/roles/artifactory/defaults/main.yml new file mode 100644 index 0000000..1867abf --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/defaults/main.yml @@ -0,0 +1,50 @@ +--- +# defaults file for quickstart-jfrog-artifactory/scripts/roles/artifactory + +ecs_deployment: false + +db_type: mysql +db_driver: com.mysql.jdbc.Driver +db_ipaddr: 127.0.0.1 +db_name: artifactory +db_user: artuser +db_password: badpassword + +s3_endpoint: needs_to_be_passed +s3_access_key: needs_to_be_passed +s3_access_secret_key: needs_to_be_passed +s3_bucket: needs_to_be_passed + +# Differences required for nginx as a container. +artifactory_hostname: 127.0.0.1 +ssl_dir: /var/opt/jfrog/nginx/ssl +key_dir: /etc/pki/tls/private +nginx_user_id: 104 +nginx_group_id: 107 + +certificate_key_file: /root/key +certificate_file: /root/cert +art_primary: true +java_version: java-1.8.0 +extra_java_opts: -server -Xms2g -Xmx14g -Xss256k -XX:+UseG1GC +java_mysql_driver: + url: https://bintray.com/artifact/download/bintray/jcenter/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar + dest: /opt/jfrog/artifactory/tomcat/lib/mysql-connector-java-5.1.38.jar + owner: artifactory + group: artifactory +rds_cert: + url: https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem + dest: /root/rds-combined-ca-bundle.pem + owner: root + group: root + cert_alias: rds_ca +import_rds: true + + + +# The Docker scripts handle this, so we do not need these variables when configuring +# A docker system that will host +artifactory_keystore_path: /etc/alternatives/jre_1.8.0/lib/security/cacerts +artifactory_keystore_default: changeit +artifactory_keystore_pass: needs_to_be_passed + diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/inactiveServerCleaner.groovy b/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/inactiveServerCleaner.groovy new file mode 100644 index 0000000..6d7daa1 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/inactiveServerCleaner.groovy @@ -0,0 +1,46 @@ +import org.artifactory.state.ArtifactoryServerState +import org.artifactory.storage.db.servers.service.ArtifactoryServersCommonService +import org.artifactory.common.ConstantValues +import org.slf4j.Logger +import java.util.concurrent.TimeUnit +jobs { + clean(interval: 90000, delay: 900000) { + runCleanupHAInactiveServers() + } +} +executions { + cleanHAInactiveServers() { params -> + runCleanupHAInactiveServers() + } +} +def runCleanupHAInactiveServers() { + def artifactoryServersCommonService = ctx.beanForType(ArtifactoryServersCommonService) + def artifactoryInactiveServerCleaner = new ArtifactoryInactiveServersCleaner(artifactoryServersCommonService, log) + artifactoryInactiveServerCleaner.cleanInactiveArtifactoryServers() +} +public class ArtifactoryInactiveServersCleaner { + private ArtifactoryServersCommonService artifactoryServersCommonService + private Logger log + ArtifactoryInactiveServersCleaner(ArtifactoryServersCommonService artifactoryServersCommonService, Logger log) { + this.artifactoryServersCommonService = artifactoryServersCommonService + this.log = log + } + def cleanInactiveArtifactoryServers() { + log.info "Executing inactive artifactory servers cleaner plugin" + List allMembers = artifactoryServersCommonService.getAllArtifactoryServers() + for (member in allMembers) { + def heartbeat = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - member.getLastHeartbeat()) + def noHeartbeat = heartbeat > ConstantValues.haHeartbeatStaleIntervalSecs.getInt() + if (member.getServerState() == ArtifactoryServerState.UNAVAILABLE || ( noHeartbeat && member.getServerState() != ArtifactoryServerState.CONVERTING && member.getServerState() != ArtifactoryServerState.STARTING )) { + try { + log.info "Inactive artifactory servers cleaning task found server ${member.serverId} to remove" + artifactoryServersCommonService.removeServer(member.serverId) + }catch (Exception e){ + log.error "Error: Not able to remove ${member.serverId}, ${e.message}" + } + } + } + log.info "No inactive servers found" + } +} + \ No newline at end of file diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/installer-info.json b/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/installer-info.json new file mode 100644 index 0000000..5f9dafc --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/installer-info.json @@ -0,0 +1,7 @@ +{ + "productId": "JFrogInstaller_Cloudformation/1.0.0", + "features": [ + { + "featureId": "MySql/5.5" + }] +} \ No newline at end of file diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/nginx.conf b/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/nginx.conf new file mode 100644 index 0000000..ee0f4a6 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/files/nginx.conf @@ -0,0 +1,37 @@ +#user nobody; +worker_processes 1; +error_log /var/log/nginx/error.log info; +#pid logs/nginx.pid; +events { + worker_connections 1024; +} +http { + include mime.types; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + include /etc/nginx/conf.d/*.conf; + default_type application/octet-stream; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' +'$status $body_bytes_sent "$http_referer" ' +'"$http_user_agent" "$http_x_forwarded_for"'; + access_log /var/log/nginx/access.log main; + sendfile on; + #tcp_nopush on; + #keepalive_timeout 0; + keepalive_timeout 65; +} diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/handlers/main.yml b/CloudFormation-JCR-ECS/scripts/roles/artifactory/handlers/main.yml new file mode 100644 index 0000000..b988370 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/handlers/main.yml @@ -0,0 +1,13 @@ +--- +# handlers file for quickstart-jfrog-artifactory/scripts/roles/artifactory + +- name: restart nginx + service: + name: nginx + state: restarted + +- name: Enable Artifactory + service: + name: artifactory + state: started + enabled: yes diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/meta/main.yml b/CloudFormation-JCR-ECS/scripts/roles/artifactory/meta/main.yml new file mode 100644 index 0000000..3a212a9 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/meta/main.yml @@ -0,0 +1,53 @@ +galaxy_info: + author: your name + description: your description + company: your company (optional) + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: license (GPL-2.0-or-later, MIT, etc) + + min_ansible_version: 2.4 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + \ No newline at end of file diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure.yml b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure.yml new file mode 100644 index 0000000..94175a0 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure.yml @@ -0,0 +1,100 @@ +--- + +- name: Update Java + package: + name: "{{ java_version }}" + state: present + +- name: Configure Java + alternatives: + name: java + path: /usr/lib/jvm/jre-1.8.0-openjdk.x86_64/bin/java + +- name: Download Java requirements such as jbdc for mysql Driver and the RDS CA certificate + get_url: + url: "{{ item.url }}" + dest: "{{ item.dest }}" + owner: "{{ item.owner }}" + group: "{{ item.group }}" + loop: + - "{{ java_mysql_driver }}" + - "{{ rds_cert }}" + +- name: Import the RDS certificate into Java KeyStore + java_cert: + cert_path: "{{ rds_cert.dest }}" + cert_alias: "{{ rds_cert.cert_alias }}" + keystore_pass: "{{ artifactory_keystore_default }}" # Default JKS as you get from the Internet. + keystore_path: "{{ artifactory_keystore_path }}" + when: import_rds == true + register: r_java_cert + failed_when: "'Not found' in r_java_cert" + +- name: Change Keystore password + command: keytool -storepasswd -keystore {{ artifactory_keystore_path }} -storepass {{ artifactory_keystore_default }} -new {{ artifactory_keystore_pass }} + no_log: true + when: r_java_cert.rc == 0 + +- name: Configure Java + lineinfile: + path: /var/opt/jfrog/artifactory/etc/default + line: export JAVA_OPTIONS="$JAVA_OPTIONS {{ extra_java_opts }}" + create: yes + +- name: Configure Ping + lineinfile: + path: /var/opt/jfrog/artifactory/etc/artifactory.system.properties + line: artifactory.ping.allowUnauthenticated=true + create: yes + +- name: All File/Folders required for Artifactory configuration + file: + path: "{{ item.path }}" + state: "{{ item.state }}" + owner: artifactory + group: artifactory + loop: + - path: /var/opt/jfrog/artifactory/etc/security/ + state: directory + - path: /var/opt/jfrog/artifactory/etc/plugins + state: directory + - path: /var/opt/jfrog/artifactory/etc/info + state: directory + +- name: Template of the properties and certs as requires for Artifactory + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: artifactory + group: artifactory + mode: '0664' + loop: + - src: db.properties.j2 + dest: /var/opt/jfrog/artifactory/etc/db.properties + - src: binarystore.xml.j2 + dest: /var/opt/jfrog/artifactory/etc/binarystore.xml + - src: ha-node.properties.j2 + dest: /var/opt/jfrog/artifactory/etc/ha-node.properties + - src: master.key.j2 + dest: /var/opt/jfrog/artifactory/etc/security/master.key + - src: certificate.pem.j2 + dest: "{{ ssl_dir }}/cert.pem" + - src: certificate.key.j2 + dest: "{{ key_dir }}/cert.key" + - src: artifactory.cluster.license.j2 + dest: /var/opt/jfrog/artifactory/etc/artifactory.cluster.license + +- name: Copy all static files required for Artifactory + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: artifactory + group: artifactory + mode: "{{ item.mode }}" + loop: + - src: inactiveServerCleaner.groovy + dest: /var/opt/jfrog/artifactory/etc/plugins/inactiveServerCleaner.groovy + mode: '0660' + - src: installer-info.json + dest: /var/opt/jfrog/artifactory/etc/info/installer-info.json + mode: '0660' \ No newline at end of file diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure_ecs.yml b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure_ecs.yml new file mode 100644 index 0000000..e520ace --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/configure_ecs.yml @@ -0,0 +1,83 @@ +--- + +- name: All File/Folders required for Artifactory configuration + file: + path: "{{ item.path }}" + state: "{{ item.state }}" + owner: root + group: root + loop: + - path: /data/jfrog/artifactory/etc/ # Needs mapped to /artifactory_extra_conf + state: directory + - path: /data/jfrog/artifactory/tmp/plugins # Needs mapped to /tmp/plugins + state: directory + - path: /data/jfrog/artifactory/java_certs # Needs mapped to /artifactory_extra_certs + state: directory + - path: /data/jfrog/artifactory/plugins # Needs mapped to /opt/jfrog/artifactory/tomcat/lib/ + state: directory + + +- name: Download Java requirements such as jbdc for mysql Driver and the RDS CA certificate + get_url: + url: "{{ item.url }}" + dest: "{{ item.dest }}" + owner: "{{ item.owner }}" + group: "{{ item.group }}" + loop: + - "{{ java_mysql_driver }}" + - "{{ rds_cert }}" + +- name: Template of the properties as requires for Artifactory + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: '0664' + loop: + - src: binarystore.xml.j2 + dest: /data/jfrog/artifactory/etc/binarystore.xml + - src: artifactory.cluster.license.j2 + dest: /data/jfrog/artifactory/etc/artifactory.cluster.license + +- name: All File/Folders required for Artifactory configuration + file: + path: "{{ item.path }}" + state: "{{ item.state }}" + owner: "{{ nginx_user_id }}" + group: "{{ nginx_group_id }}" + loop: + - path: /data/jfrog/nginx/ssl # Mapped to /var/opt/jfrog/nginx + state: directory + - path: /data/jfrog/nginx/conf.d # Mapped to /var/opt/jfrog/nginx + state: directory + +- name: Template nginx files as requires for Artifactory + template: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: "{{ nginx_user_id }}" + group: "{{ nginx_group_id }}" + mode: '0664' + loop: + - src: certificate.pem.j2 + dest: "{{ ssl_dir }}cert.pem" + - src: certificate.key.j2 + dest: "{{ key_dir }}cert.key" + - src: artifactory.conf.j2 + dest: /data/jfrog/nginx/conf.d/artifactory.conf + +- name: Copy all static files required for Artifactory + copy: + src: "{{ item.src }}" + dest: "{{ item.dest }}" + owner: root + group: root + mode: "{{ item.mode }}" + loop: + - src: inactiveServerCleaner.groovy + dest: /data/jfrog/artifactory/tmp/plugins/inactiveServerCleaner.groovy + mode: '0777' + + + diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/install.yml b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/install.yml new file mode 100644 index 0000000..1eb4b5c --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/install.yml @@ -0,0 +1,18 @@ +--- + +- name: Add Artifactory Repo + yum_repository: + name: bintray--jfrog-artifactory-pro-rpms + description: bintray--jfrog-artifactory-pro-rpms + baseurl: https://jfrog.bintray.com/artifactory-pro-rpms + gpgcheck: no + enabled: yes + +- name: Install Artifactory from RPM + yum: + name: "jfrog-artifactory-pro-{{ artifactory_version }}" + state: installed + releasever: "{{ artifactory_version }}" + enablerepo: bintray--jfrog-artifactory-pro-rpms + disablerepo: "epel,amzn-main,amzn-updates" + notify: Enable Artifactory diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/main.yml b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/main.yml new file mode 100644 index 0000000..a24e74b --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/main.yml @@ -0,0 +1,17 @@ +--- +# tasks file for quickstart-jfrog-artifactory/scripts/roles/artifactory + + +- name: Configure an Instance to host Artifactory + include: "{{ item.name }}" + when: ecs_deployment == false + loop: + - name: install.yml + - name: configure.yml + - name: nginx-setup.yml + +- name: Configure ECS EC2 Node to host an Artifactory Container + include: configure_ecs.yml + when: ecs_deployment == true + + diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/nginx-setup.yml b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/nginx-setup.yml new file mode 100644 index 0000000..62d6d6a --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/tasks/nginx-setup.yml @@ -0,0 +1,26 @@ +--- + +# Tasks for configuring NGINX for Artifactory +- name: Ensure latest nginx is installed + package: + name: nginx + state: latest + +- name: Configure main NGINX conf file. + copy: + src: nginx.conf + dest: /etc/nginx/nginx.conf + owner: root + group: root + mode: '0755' + notify: restart nginx + + +- name: Configure the Artifactory NGINX conf + template: + src: artifactory.conf.j2 + dest: /etc/nginx/conf.d/artifactory.conf + owner: root + group: root + mode: '0755' + notify: restart nginx diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.cluster.license.j2 b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.cluster.license.j2 new file mode 100644 index 0000000..88e5571 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.cluster.license.j2 @@ -0,0 +1,18 @@ +{% if artifactory_license1 |length %} +{{ artifactory_license1 }} +{% endif %} + + +{% if artifactory_license2 |length %} +{{ artifactory_license2 }} +{% endif %} + + +{% if artifactory_license3 |length %} +{{ artifactory_license3 }} +{% endif %} + + +{% if artifactory_license4 |length %} +{{ artifactory_license4 }} +{% endif %} \ No newline at end of file diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.conf.j2 b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.conf.j2 new file mode 100644 index 0000000..7fb7fcf --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/artifactory.conf.j2 @@ -0,0 +1,33 @@ +ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; +ssl_certificate {{ ssl_dir }}/cert.pem; +ssl_certificate_key {{ key_dir }}/cert.key; +ssl_session_cache shared:SSL:1m; +ssl_prefer_server_ciphers on; +## server configuration +server { + listen 443 ssl; + listen 80 ; + server_name {{ artifactory_server_name }}.{{ certificate_domain }} ~(?.+)\.{{ certificate_domain }}; + if ($http_x_forwarded_proto = '') { + set $http_x_forwarded_proto $scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /artifactory/webapp/ redirect; + rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; + rewrite ^/(v2)/(.*) /artifactory/$1/$2; + chunked_transfer_encoding on; + client_max_body_size 0; + location /artifactory/ { + proxy_read_timeout 900; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://{{ artifactory_hostname }}:8081/artifactory/; + proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port/artifactory; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/binarystore.xml.j2 b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/binarystore.xml.j2 new file mode 100644 index 0000000..691eb3e --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/binarystore.xml.j2 @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + crossNetworkStrategy + crossNetworkStrategy + 2 + 1 + + + + + remote + + + + local + + + + {{ s3_endpoint }} + {{ s3_access_key }} + {{ s3_access_secret_key }} + {{ s3_bucket }} + + + diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.key.j2 b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.key.j2 new file mode 100644 index 0000000..4ac8f0f --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.key.j2 @@ -0,0 +1 @@ +{{ certificate_key | b64decode }} diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.pem.j2 b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.pem.j2 new file mode 100644 index 0000000..9bc0562 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/certificate.pem.j2 @@ -0,0 +1,2 @@ +{{ certificate | b64decode }} + diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/db.properties.j2 b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/db.properties.j2 new file mode 100644 index 0000000..f92ba21 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/db.properties.j2 @@ -0,0 +1,5 @@ +type={{ db_type }} +driver={{ db_driver }} +url=jdbc:mysql://{{ db_ipaddr }}:3306/{{ db_name }}?characterEncoding=UTF-8&elideSetAutoCommits=true&verifyServerCertificate=true&useSSL=true&requireSSL=true +username={{ db_user }} +password={{ db_password }} \ No newline at end of file diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/ha-node.properties.j2 b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/ha-node.properties.j2 new file mode 100644 index 0000000..bd6683b --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/ha-node.properties.j2 @@ -0,0 +1,9 @@ +{% if art_primary == True %} +node.id=primary +{% else %} +node.id={{ ansible_hostname }} +{% endif %} +artifactory.ha.data.dir=/var/opt/jfrog/artifactory/data +context.url=http://{{ ansible_default_ipv4.address }}:8081/artifactory +membership.port=0 +primary={{ art_primary }} diff --git a/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/master.key.j2 b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/master.key.j2 new file mode 100644 index 0000000..0462a64 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/roles/artifactory/templates/master.key.j2 @@ -0,0 +1 @@ +{{ master_key }} \ No newline at end of file diff --git a/CloudFormation-JCR-ECS/scripts/site-artifactory.yml b/CloudFormation-JCR-ECS/scripts/site-artifactory.yml new file mode 100644 index 0000000..29b2f06 --- /dev/null +++ b/CloudFormation-JCR-ECS/scripts/site-artifactory.yml @@ -0,0 +1,5 @@ +- hosts: localhost + gather_facts: true + become: true + roles: + - name: artifactory diff --git a/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-ec2.template.yaml b/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-ec2.template.yaml new file mode 100755 index 0000000..ee2e9be --- /dev/null +++ b/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-ec2.template.yaml @@ -0,0 +1,399 @@ +AWSTemplateFormatVersion: "2010-09-09" +Description: "Deploys the EC2 Autoscaling, LaunchConfig, ECS Cluster, and calls nested Stack for the ECS Service" +Parameters: + PrivateSubnet1ID: + Type: 'AWS::EC2::Subnet::Id' + PrivateSubnet2ID: + Type: 'AWS::EC2::Subnet::Id' + MinScalingNodes: + Type: Number + MaxScalingNodes: + Type: Number + InstanceType: + Type: String + VolumeSize: + Type: Number + ClusterName: + Description: Desired name for your cluster. + Default: JFrog + Type: String + CreateNewECSCluster: + Description: Whether to create the ECS Cluster with given name or not. + Default: Enabled + Type: String + DeploymentTag: + Type: String + NumberOfSecondary: + Type: Number + ArtifactoryLicense1: + Type: String + ArtifactoryLicense2: + Type: String + ArtifactoryLicense3: + Type: String + ArtifactoryLicense4: + Type: String + ArtifactoryServerName: + Type: String + CertificateDomain: + Type: String + ArtifactoryIAMAcessKey: + Type: String + NoEcho: 'true' + SecretAccessKey: + Type: String + NoEcho: 'true' + ArtifactoryS3Bucket: + Type: String + CertificateKey: + Type: String + NoEcho: 'true' + Certificate: + Type: String + DBType: + Type: String + DBPluginUrl: + Default: https://bintray.com/artifact/download/bintray/jcenter/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar + Type: String + DBPlugin: + Default: mysql-connector-java-5.1.38.jar + Type: String + ArtifactoryDBEndpointAddress: + Type: String + DatabaseName: + Type: String + DatabaseUser: + Type: String + DatabasePassword: + NoEcho: 'true' + Type: String + MasterKey: + Type: String + NoEcho: 'true' + ExtraJavaOptions: + Type: String + ArtifactoryVersion: + Type: String + KeyPairName: + Type: AWS::EC2::KeyPair::KeyName + ArtifactoryTargetGroupArn: + Type: String + SecurityGroups: + Type: String + AnsibleVaultPass: + Description: Ansiblevault Password to secure the artifactory.yml + NoEcho: 'true' + Type: String + QSS3BucketName: + Type: String + QSS3KeyPrefix: + Type: String +Mappings: + AWSAMIRegionMap: + #AMI: + # AMZECSOTP: amzn-ami-2018.03.a-amazon-ecs-optimized + us-east-2: + AMI: ami-0307f7ccf6ea35750 + us-east-1: + AMI: ami-045f1b3f87ed83659 + us-west-2: + AMI: ami-01b70aea4161476b7 + us-west-1: + AMI: ami-0285183bbef6224bd + eu-west-3: + AMI: ami-0f4738fbeb53e6c3a + eu-west-2: + AMI: ami-01bee3897bba49d78 + eu-west-1: + AMI: ami-0627e141ce928067c + eu-central-1: + AMI: ami-0eaa3baf6969912ba + eu-north-1: + AMI: ami-03494b0c9e1c22492 + ap-northeast-2: + AMI: ami-00294948a592fc052 + ap-northeast-1: + AMI: ami-05b296a384694dfa4 + ap-southeast-2: + AMI: ami-02c73ee1100ce3e7a + ap-southeast-1: + AMI: ami-050865a806e0dae53 + ca-central-1: + AMI: ami-0f552e0a86f08b660 + ap-south-1: + AMI: ami-01ef9f6a829ae3956 + sa-east-1: + AMI: ami-084b1eee100c102ee +Conditions: + CreateECSCluster: !Equals [!Ref 'CreateNewECSCluster', 'Enabled'] + GovCloudCondition: !Equals + - !Ref 'AWS::Region' + - us-gov-west-1 +Resources: + ECSRole: + Type: AWS::IAM::Role + Properties: + Path: / + RoleName: !Sub + ${ClusterName}-ECSRole-${AWS::Region} + AssumeRolePolicyDocument: + Statement: + - Action: + - sts:AssumeRole + Principal: + Service: + - ecs-tasks.amazonaws.com + - ec2.amazonaws.com + - ecs.amazonaws.com + Effect: Allow + Version: 2012-10-17 + ManagedPolicyArns: + - 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM' + - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy + - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role + Policies: + - PolicyName: ecs-service + PolicyDocument: + Statement: + - Effect: Allow + Action: + - ecs:ListClusters + - ecs:ListServices + - ecs:DescribeServices + - ecr:ListImages + - ecs:RegisterTaskDefinition + - ecs:CreateService + - ecs:ListTasks + - ecs:DescribeTasks + - ecs:CreateService + - ecs:DeleteService + - ecs:UpdateService + - ecs:DescribeContainerInstances + - ecs:DescribeTaskDefinition + - application-autoscaling:DescribeScalableTargets + - iam:ListRoles + Resource: "*" + ECSInstanceProfile: + Type: AWS::IAM::InstanceProfile + Properties: + Path: / + Roles: + - !Ref ECSRole + ECSCluster: + Condition: CreateECSCluster + Type: AWS::ECS::Cluster + Properties: + ClusterName: !Ref ClusterName + ArtifactoryScalingGroup: + Type: 'AWS::AutoScaling::AutoScalingGroup' + Properties: + AutoScalingGroupName: ArtifactoryECSEC2ScaleGroup + LaunchConfigurationName: !Ref ArtifactoryLaunchConfiguration + VPCZoneIdentifier: + - !Ref PrivateSubnet1ID + - !Ref PrivateSubnet2ID + MinSize: !Ref MinScalingNodes + MaxSize: !Ref MaxScalingNodes + Cooldown: '300' + DesiredCapacity: !Ref MinScalingNodes + HealthCheckType: EC2 + HealthCheckGracePeriod: 600 + Tags: + - Key: Name + Value: !Ref DeploymentTag + PropagateAtLaunch: true + CreationPolicy: + ResourceSignal: + Count: 1 + Timeout: PT30M + ArtifactoryLaunchConfiguration: + Type: 'AWS::AutoScaling::LaunchConfiguration' + Metadata: + 'AWS::CloudFormation::Authentication': + S3AccessCreds: + type: S3 + roleName: + - !Ref ECSRole + buckets: + - !Ref QSS3BucketName + 'AWS::CloudFormation::Init': + configSets: + artifactory_install: + - "config-artifactory-master" + - "secure-artifactory" + config-artifactory-master: + files: + /root/.artifactory_ansible/artifactory.yml: + content: !Sub + - | + # Base install for Artifactory + - import_playbook: site-artifactory.yml + vars: + ecs_deployment: true + artifactory_hostname: artifactory + ssl_dir: /data/jfrog/nginx/ssl/ + key_dir: /data/jfrog/nginx/ssl/ + artifactory_license1: ${ArtifactoryLicense1} + artifactory_license2: ${ArtifactoryLicense2} + artifactory_license3: ${ArtifactoryLicense3} + artifactory_license4: ${ArtifactoryLicense4} + s3_endpoint: s3.${AWS::Region}.amazonaws.com + s3_access_key: ${ArtifactoryIAMAcessKey} + s3_access_secret_key: ${SecretAccessKey} + s3_bucket: ${ArtifactoryS3Bucket} + artifactory_server_name: ${ArtifactoryServerName} + certificate_domain: ${CertificateDomain} + certificate: ${cert} + certificate_key: ${cert_key} + java_mysql_driver: + url: ${DBPluginUrl} + dest: /data/jfrog/artifactory/plugins/${DBPlugin} + owner: root + group: root + rds_cert: + url: https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem + dest: /data/jfrog/artifactory/java_certs/rds-combined-ca-bundle.pem + owner: root + group: root + - cert: !Base64 + "Fn::Sub": "${Certificate}" + cert_key: !Base64 + "Fn::Sub": "${CertificateKey}" + mode: "0400" + /root/.vault_pass.txt: + content: !Sub | + ${AnsibleVaultPass} + mode: "0400" + /root/.secureit.sh: + content: /usr/local/bin/ansible-vault encrypt /root/.artifactory_ansible/artifactory.yml --vault-id /root/.vault_pass.txt + mode: "0770" + secure-artifactory: + commands: + 'secure ansible playbook': + command: '/root/.secureit.sh' + ignoreErrors: 'false' + Properties: + AssociatePublicIpAddress: false + KeyName: !Ref KeyPairName + IamInstanceProfile: !Ref ECSInstanceProfile + ImageId: !FindInMap + - AWSAMIRegionMap + - !Ref 'AWS::Region' + - AMI + SecurityGroups: + - !Ref SecurityGroups + InstanceType: !Ref InstanceType + LaunchConfigurationName: ArtifactoryECSEC2LaunchConfig + BlockDeviceMappings: + - DeviceName: /dev/xvda + Ebs: + VolumeSize: !Ref VolumeSize + VolumeType: gp2 + DeleteOnTermination: true + UserData: !Base64 + 'Fn::Sub': + - > + #!/bin/bash -x + + #CFN Functions + + function cfn_fail + + { + + cfn-signal -e 1 --stack ${AWS::StackName} --region ${AWS::Region} + --resource ArtifactoryScalingGroup + + exit 1 + + } + + function cfn_success + + { + + cfn-signal -e 0 --stack ${AWS::StackName} --region ${AWS::Region} + --resource ArtifactoryScalingGroup + + exit 0 + + } + + echo ECS_CLUSTER=${ClusterName} >> /etc/ecs/ecs.config + + S3URI=https://${QSS3BucketName}.${S3Region}.amazonaws.com/${QSS3KeyPrefix} + + yum install -y git + + echo $PATH + + PATH=/usr/local/bin/:/opt/aws/bin:$PATH + + echo $PATH + echo \'[Cloning: Load QuickStart Common Utils]\' + + git clone + https://github.com/aws-quickstart/quickstart-linux-utilities.git + + source /quickstart-linux-utilities/quickstart-cfn-tools.source + + echo \'[Loaded: Load QuickStart Common Utils]\' + + echo \'[Update Operating System]\' + + qs_update-os || qs_err + + qs_bootstrap_pip || qs_err + + qs_aws-cfn-bootstrap || qs_err + + pip install awscli &> /var/log/userdata.awscli_install.log || qs_err " awscli install failed " + + pip install ansible &> /var/log/userdata.ansible_install.log || qs_err " ansible install failed " + + mkdir ~/.artifactory_ansible + + aws s3 sync s3://${QSS3BucketName}/${QSS3KeyPrefix}scripts/ ~/.artifactory_ansible/ + + cfn-init -v --stack ${AWS::StackName} --resource + ArtifactoryLaunchConfiguration --configsets artifactory_install + --region ${AWS::Region} || cfn_fail + + export ANSIBLE_VAULT_PASSWORD_FILE="/root/.vault_pass.txt" + + /usr/local/bin/ansible-playbook /root/.artifactory_ansible/artifactory.yml + + rm -rf /root/.secureit.sh + + [ $(qs_status) == 0 ] && cfn_success || cfn_fail + - S3Region: !If + - GovCloudCondition + - s3-us-gov-west-1 + - s3 + ECSLogGroup: + Type: AWS::Logs::LogGroup + Properties: + RetentionInDays: 7 + PrimaryStack: + DependsOn: ArtifactoryScalingGroup + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-ecs.template.yaml' + Parameters: + ECSCluster: !Ref ClusterName # In case we do not build the cluster we still require the Name of the cluster built. + ServiceName: ArtifactoryPrimary + ArtifactoryTargetGroupArn: !Ref ArtifactoryTargetGroupArn + ArtifactoryVersion: !Ref ArtifactoryVersion + DBPlugin: !Ref DBPlugin + MasterKey: !Ref MasterKey + ExtraJavaOptions: !Ref ExtraJavaOptions + NumberNodes: "1" + ArtifactoryPrimary: "true" + DBType: !Ref DBType + DatabaseUser: !Ref DatabaseUser + DatabaseName: !Ref DatabaseName + DatabasePassword: !Ref DatabasePassword + ArtifactoryDBEndpointAddress: !Ref ArtifactoryDBEndpointAddress + ECSLogGroup: !Ref ECSLogGroup + ECSRoleArn: + Fn::GetAtt: ECSRole.Arn diff --git a/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-existing-vpc.template.yaml b/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-existing-vpc.template.yaml new file mode 100755 index 0000000..f27cd43 --- /dev/null +++ b/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-existing-vpc.template.yaml @@ -0,0 +1,704 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: 'JFrog Artifactory Quick Start Deployment into an Existing VPC (qs-1q037eflr)' +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Security configuration + Parameters: + - KeyPairName + - AccessCIDR + - RemoteAccessCIDR + - Label: + default: Network Configuration + Parameters: + - VPCID + - VPCCIDR + - PublicSubnet1ID + - PublicSubnet2ID + - PrivateSubnet1ID + - PrivateSubnet2ID + - PrivateSubnet1CIDR + - PrivateSubnet2CIDR + - ELBScheme + - Label: + default: Bastion Configuration + Parameters: + - ProvisionBastionHost + - BastionInstanceType + - BastionOS + - BastionRootVolumeSize + - BastionEnableTCPForwarding + - NumBastionHosts + - BastionEnableX11Forwarding + - Label: + default: ECS Configuration + Parameters: + - ClusterName + - CreateNewECSCluster + - InstanceType + - VolumeSize + - Label: + default: JFrog Artifactory Configuration + Parameters: + - ArtifactoryVersion + - NumberOfSecondary + - NumberOfEC2Nodes + - SMLicensesName + - Certificate + - CertificateKey + - CertificateDomain + - ArtifactoryServerName + - MasterKey + - ExtraJavaOptions + - AnsibleVaultPass + - Label: + default: Amazon RDS Configuration + Parameters: + - DatabaseName + - DatabaseEngine + - DatabaseVersion + - DatabaseUser + - DatabasePassword + - DatabaseInstance + - DBAllocatedStorage + - MultiAZDatabase + - Label: + default: AWS Quick Start Configuration + Parameters: + - QSS3BucketName + - QSS3KeyPrefix + ParameterLabels: + KeyPairName: + default: SSH key name + AccessCIDR: + default: Permitted IP range + RemoteAccessCIDR: + default: Remote access CIDR + VPCID: + default: VPC ID + VPCCIDR: + default: VPC CIDR + PublicSubnet1ID: + default: Public subnet 1 ID + PublicSubnet2ID: + default: Public subnet 2 ID + PrivateSubnet1ID: + default: Private subnet 1 ID + PrivateSubnet2ID: + default: Private subnet 2 ID + PrivateSubnet1CIDR: + default: Private subnet 1 CIDR + PrivateSubnet2CIDR: + default: Private subnet 2 CIDR + ELBScheme: + default: Elastic Load Balancer scheme + ProvisionBastionHost: + default: Bastion instance + BastionInstanceType: + default: Bastion instance type + BastionRootVolumeSize: + default: Bastion root volume size + BastionEnableTCPForwarding: + default: Bastion enable TCP forwarding + BastionEnableX11Forwarding: + default: Bastion enable X11 forwarding + BastionOS: + default: Bastion operating system + NumBastionHosts: + default: Number of bastion instances + ClusterName: + default: ECS cluster name + CreateNewECSCluster: + default: Create new ECS cluster + InstanceType: + default: EC2 instance type + VolumeSize: + default: EBS root volume size + ArtifactoryVersion: + default: Artifactory version + NumberOfSecondary: + default: Number of secondary instances + NumberOfEC2Nodes: + default: Number of EC2 nodes + SMLicensesName: + default: Artifactory licenses secret name + Certificate: + default: Certificate + CertificateKey: + default: Certificate key + CertificateDomain: + default: Certificate domain + ArtifactoryServerName: + default: Artifactory server name + MasterKey: + default: Master server key + ExtraJavaOptions: + default: Extra Java options + AnsibleVaultPass: + default: Ansible Vault password + DatabaseName: + default: Database name + DatabaseEngine: + default: Database engine + DatabaseVersion: + default: Database version + DatabaseUser: + default: Database user + DatabasePassword: + default: Database password + DatabaseInstance: + default: Database instance type + DBAllocatedStorage: + default: Database allocated storage + MultiAZDatabase: + default: High available database + QSS3BucketName: + default: Quick Start S3 bucket name + QSS3KeyPrefix: + default: Quick Start S3 key prefix + +Parameters: + KeyPairName: + Description: The name of an existing public/private key pair, which allows you + to securely connect to your instance after it launches. + Type: AWS::EC2::KeyPair::KeyName + AccessCIDR: + Description: The CIDR IP range that is permitted to access Artifactory. + We recommend that you set this value to a trusted IP range. + For example, you might want to grant only your corporate network access to the software. + 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ + Type: String + RemoteAccessCIDR: + Description: The remote CIDR range for allowing SSH into the Bastion instance. + We recommend that you set this value to a trusted IP range. + For example, you might want to grant specific ranges inside your corporate network SSH access. + 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ + Type: String + VPCID: + Description: The ID of your existing VPC (e.g., vpc-0343606e). + Type: "AWS::EC2::VPC::Id" + VPCCIDR: + Description: The CIDR block for the VPC. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.0.0/16 + Type: String + PublicSubnet1ID: + Description: The ID of the public subnet in Availability Zone 1 in your existing VPC (e.g., subnet-z0376dab). + Type: "AWS::EC2::Subnet::Id" + PublicSubnet2ID: + Description: The ID of the public subnet in Availability Zone 2 in your existing VPC (e.g., subnet-a29c3d84). + Type: "AWS::EC2::Subnet::Id" + PrivateSubnet1ID: + Description: The ID of the private subnet in Availability Zone 1 in your existing VPC (e.g., subnet-a0246dcd). + Type: "AWS::EC2::Subnet::Id" + PrivateSubnet2ID: + Description: The ID of the private subnet in Availability Zone 2 in your existing VPC (e.g., subnet-b58c3d67). + Type: "AWS::EC2::Subnet::Id" + PrivateSubnet1CIDR: + Description: The CIDR of the private subnet in Availability Zone 1 in your existing VPC (e.g., 10.0.0.0/19). + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.0.0/19 + Type: String + PrivateSubnet2CIDR: + Description: The CIDR of the private subnet in Availability Zone 2 in your existing VPC (e.g., 10.0.32.0/19). + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.32.0/19 + Type: String + ProvisionBastionHost: + Description: Choose Disabled to skip creating a bastion instance. Due to the Artifactory nodes being + created in private subnets, the default setting of Enabled this is highly recommended. + AllowedValues: + - "Enabled" + - "Disabled" + Default: "Enabled" + Type: String + BastionInstanceType: + Description: The size of the bastion instances. + AllowedValues: + - t2.nano + - t2.micro + - t2.small + - t2.medium + - t2.large + - m3.large + - m3.xlarge + - m3.2xlarge + - m4.large + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + Default: "t2.micro" + Type: String + BastionRootVolumeSize: + Description: The size of the root volume on the bastion instances. + Default: 10 + Type: Number + BastionEnableTCPForwarding: + Description: Choose whether to enable TCPForwarding via the bootstrapping of the bastion instance + or not. + AllowedValues: + - "true" + - "false" + Default: "true" + Type: String + BastionEnableX11Forwarding: + Description: Choose true to enable X11 via the bootstrapping of the bastion host. + Setting this value to true will enable X Windows over SSH. + X11 forwarding can be very useful but it is also a security risk, so we recommend + that you keep the default (false) setting unless required. + AllowedValues: + - "true" + - "false" + Default: "false" + Type: String + BastionOS: + Description: The Linux distribution for the Amazon Machine Image (AMI) to be used for the bastion instances. + AllowedValues: + - "Amazon-Linux-HVM" + - "CentOS-7-HVM" + - "Ubuntu-Server-14.04-LTS-HVM" + - "Ubuntu-Server-16.04-LTS-HVM" + - "SUSE-SLES-15-HVM" + Default: "Amazon-Linux-HVM" + Type: String + NumBastionHosts: + Description: The number of bastion instances to create. + AllowedValues: + - '1' + - '2' + - '3' + - '4' + Default: '1' + Type: String + ClusterName: + Description: The name for your ECS cluster. + Default: JFrog + Type: String + CreateNewECSCluster: + Description: Choose whether to create a new ECS cluster with the name specified in the 'ClusterName' parameter. + If you choose Disabled, an ECS cluster with the name specified in the 'CluserName' parameter must already exist. + AllowedValues: + - "Enabled" + - "Disabled" + Default: "Enabled" + Type: String + InstanceType: + Description: The EC2 instance type for the Artifactory Docker hosts. + AllowedValues: + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + - m4.10xlarge + ConstraintDescription: Must contain valid instance type. + Default: m4.xlarge + Type: String + VolumeSize: + Description: The size in GB of the available storage; the Quick Start will create an + Amazon Elastic Block Store (Amazon EBS) volumes of this size. + Default: 200 + Type: Number + NumberOfEC2Nodes: + Description: The number of EC2 nodes to create for the ECS cluster. There must be + enough nodes to run the number of secondaries plus the primary task. + AllowedValues: + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + Default: 3 + Type: Number + NumberOfSecondary: + Description: The number of secondary Artifactory servers to complete your + HA deployment. To fit the Artifactory best practices, the minimum number + is two; the maximum is seven. Do not select more than instances than you + have licenses for. + AllowedValues: + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + Default: 2 + Type: Number + ArtifactoryVersion: + Description: The version of Artifactory that you want to deploy into the Quick Start. + Please see the release notes to select the version you want to deploy. + https://www.jfrog.com/confluence/display/RTF/Release+Notes + #AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ + #ConstraintDescription: A version that matches X.X.X per Artifactory releases. + Default: 6.15.0 + Type: String + SMLicensesName: + Description: The secret name created in AWS Secrets Manager which contains the Artifactory licenses. + Type: String + Certificate: + Description: The certificate file to be used to terminate SSL. + AllowedPattern: ^(-----BEGIN CERTIFICATE-----)\n(.*?\n)+(-----END CERTIFICATE-----)$ + ConstraintDescription: A Certificate that begins with "-----BEGIN CERTIFICATE----- " and ends with "-----END CERTIFICATE----- " + Type: String + CertificateKey: + Description: The private key for the certificate. + AllowedPattern: ^(-----BEGIN [A-Za-z ]+ KEY-----)\n(.*?\n)+(-----END [A-Za-z ]+ KEY-----)$ + ConstraintDescription: A Private key that begins with "-----BEGIN PRIVATE KEY-----" and ends with "-----END PRIVATE KEY-----" + NoEcho: 'true' + Type: String + CertificateDomain: + Description: The domain matching that of the certificate. Ensure that it matches your certificate. + AllowedPattern: ^[A-Za-z0-9]+[.A-Za-z0-9]+[A-Za-z0-9]$ + ConstraintDescription: The domain must not start or end with a '.' + Type: String + ArtifactoryServerName: + Description: The name of your Artifactory server. Ensure that this matches your certificate. + Type: String + MasterKey: + Description: The master key for the Artifactory cluster. Generate a master key by using the command '$openssl rand -hex 16'. + AllowedPattern: ^[a-zA-Z0-9]+$ + MinLength: '1' + MaxLength: '64' + ConstraintDescription: Only capital or lowercase letters and numbers, with a Max of 64 characters. + NoEcho: 'true' + Type: String + ExtraJavaOptions: + Description: Setting Java memory parameters for Artifactory. For more information, see the Artifactory + system requirements. + https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware. + Default: -Xmx4g + Type: String + AnsibleVaultPass: + Description: The Ansible Vault password to protect the Artifactory YAML configuration file + generated during the Artifactory deployment. This YAML file is stored on the EC2 nodes + and secured with this password. + NoEcho: 'true' + Type: String + DatabaseName: + Description: The name for your DB instance. The name must be unique across all DB instances + owned by your AWS account in the current AWS Region. The DB instance identifier is case-insensitive, + but is stored as all lowercase (as in "mydbinstance"). + AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ + MinLength: '1' + MaxLength: '60' + ConstraintDescription: 1 to 60 alphanumeric characters First character must be a letter. + Default: artdb + Type: String + DatabaseEngine: + Description: The database engine that you want to run, currently locked to MySQL. + AllowedValues: + - MySQL + Default: MySQL + Type: String + DatabaseVersion: + Description: The major version of the MySQL database engine you want to run. This is currently locked to MySQL versions + supported by Artifactory and RDS. + AllowedValues: + - 5.5 + - 5.6 + - 5.7 + Default: 5.7 + Type: String + DatabaseUser: + Description: The login ID for the master user of your DB instance. + MinLength: '1' + MaxLength: '16' + AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ + ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter + Default: artifactory + Type: String + DatabasePassword: + Description: The password for the Artifactory database user. + AllowedPattern: ^[^ \\']+$ + MinLength: '8' + MaxLength: '12' + ConstraintDescription: Must be at least 8 and no more than + 12 characters containing letters and (minimum 1 capital letter), numbers and + symbols. + NoEcho: 'true' + Type: String + DatabaseInstance: + Description: The size of the database to be deployed as part of the Quick Start. + AllowedValues: + - db.m3.medium + - db.m3.large + - db.m3.xlarge + - db.m3.2xlarge + - db.m4.large + - db.m4.xlarge + - db.m4.2xlarge + - db.m4.10xlarge + - db.m4.16xlarge + - db.m5.large + - db.m5.xlarge + - db.m5.2xlarge + - db.m5.4xlarge + - db.m5.12xlarge + - db.m5.24xlarge + ConstraintDescription: Must be a valid database Instance Type. + Default: db.m4.large + Type: String + DBAllocatedStorage: + Description: The size in GB of the available storage for the database instance. + MinValue: 5 + MaxValue: 1024 + Default: 10 + Type: Number + MultiAZDatabase: + Description: Choose false to create an Amazon RDS instance in a single Availability Zone. + ConstraintDescription: True or False + AllowedValues: + - "true" + - "false" + Default: "true" + Type: String + ELBScheme: + Description: Choose whether this will be internet facing or internal. + AllowedValues: + - internal + - internet-facing + Default: internet-facing + Type: String + QSS3BucketName: + Description: S3 bucket name for the Quick Start assets. This string can include + numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start + or end with a hyphen (-). + AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ + ConstraintDescription: Quick Start bucket name can include numbers, lowercase + letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen + (-). + Default: aws-quickstart + Type: String + QSS3KeyPrefix: + Description: S3 key prefix for the Quick Start assets. Quick Start key prefix + can include numbers, lowercase letters, uppercase letters, hyphens (-), and + forward slash (/). + AllowedPattern: ^[0-9a-zA-Z-/]*$ + ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, + uppercase letters, hyphens (-), and forward slash (/). + Default: quickstart-jfrog-artifactory/ + Type: String +Conditions: + EnableBastion: !Equals [!Ref 'ProvisionBastionHost', 'Enabled'] +Resources: + BastionStack: + Condition: EnableBastion + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-linux-bastion/templates/linux-bastion.template' + Parameters: + VPCID: !Ref VPCID + PublicSubnet1ID: !Ref PublicSubnet1ID + PublicSubnet2ID: !Ref PublicSubnet2ID + KeyPairName: !Ref KeyPairName + QSS3BucketName: !Ref QSS3BucketName + QSS3KeyPrefix: !Sub '${QSS3KeyPrefix}submodules/quickstart-linux-bastion/' + RemoteAccessCIDR: !Ref RemoteAccessCIDR + BastionInstanceType: !Ref BastionInstanceType + RootVolumeSize: !Ref BastionRootVolumeSize + BastionAMIOS: !Ref BastionOS + EnableTCPForwarding: !Ref BastionEnableTCPForwarding + EnableX11Forwarding: !Ref BastionEnableX11Forwarding + NumBastionHosts: !Ref NumBastionHosts + ArtifactoryCoreInfraStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub "https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-artifactory-core-infrastructure.template.yaml" + Parameters: + VPCID: !Ref VPCID + VPCCIDR: !Ref VPCCIDR + PrivateSubnet1CIDR: !Ref PrivateSubnet1CIDR + PrivateSubnet2CIDR: !Ref PrivateSubnet2CIDR + PrivateSubnet3CIDR: !Ref PrivateSubnet2CIDR # This should end up in no new rule but required for EKS + SubnetIds: !Join [ ",", [ !Ref PrivateSubnet1ID, !Ref PrivateSubnet2ID ]] + DBAllocatedStorage: !Ref DBAllocatedStorage + MultiAZDatabase: !Ref MultiAZDatabase + DatabaseEngine: !Ref DatabaseEngine + DatabaseVersion: !Ref DatabaseVersion + DatabaseUser: !Ref DatabaseUser + DatabasePassword: !Ref DatabasePassword + DatabaseInstance: !Ref DatabaseInstance + DatabaseName: !Ref DatabaseName + ArtifactoryELB: + Type: AWS::ElasticLoadBalancingV2::LoadBalancer + Properties: + IpAddressType: ipv4 + Name: ArtifactoryELB + Scheme: !Ref ELBScheme + Subnets: + - !Ref PublicSubnet1ID + - !Ref PublicSubnet2ID + Tags: + - Key: Name + Value: artifactory-ELB + Type: network + ArtifactoryTargetGroup: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckEnabled: True + HealthCheckIntervalSeconds: 30 + HealthCheckProtocol: TCP + HealthCheckTimeoutSeconds: 10 + HealthyThresholdCount: 3 + Name: Artifactory + Port: 443 + Protocol: TCP + #Tags: + # - !Ref DeploymentTag + TargetType: instance + UnhealthyThresholdCount: 3 + VpcId: !Ref VPCID + ArtifactoryELBListener: + Type: AWS::ElasticLoadBalancingV2::Listener + Properties: + DefaultActions: + - TargetGroupArn: !Ref ArtifactoryTargetGroup + Type: forward + LoadBalancerArn: !Ref ArtifactoryELB + Port: 443 + Protocol: TCP + ArtifactoryELBSG: + Type: AWS::EC2::SecurityGroup + Properties: + Tags: + - Key: Name + Value: artifactory-ELB-sg + GroupDescription: SG for ELB Ingress from outside and egress to instances + VpcId: !Ref VPCID + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: !Ref AccessCIDR + - IpProtocol: tcp + FromPort: 443 + ToPort: 443 + CidrIp: !Ref AccessCIDR + - IpProtocol: tcp + FromPort: 8081 + ToPort: 8081 + CidrIp: !Ref AccessCIDR + SecurityGroupEgress: + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 443 + ToPort: 443 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 8081 + ToPort: 8081 + CidrIp: 0.0.0.0/0 + ArtifactoryEC2SG: + Type: AWS::EC2::SecurityGroup + Properties: + Tags: + - Key: Name + Value: artifactory-ec2-instances-sg + GroupDescription: SG for EC2 instances (also permits SSH access from the bastion host) + VpcId: !Ref VPCID + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: !Ref VPCCIDR + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: !Ref VPCCIDR + - IpProtocol: tcp + FromPort: 443 + ToPort: 443 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 8081 + ToPort: 8081 + CidrIp: !Ref PrivateSubnet1CIDR + - IpProtocol: tcp + FromPort: 8081 + ToPort: 8081 + CidrIp: !Ref PrivateSubnet2CIDR + SecurityGroupEgress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 443 + ToPort: 443 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 3306 + ToPort: 3306 + CidrIp: !Ref PrivateSubnet1CIDR + - IpProtocol: tcp + FromPort: 3306 + ToPort: 3306 + CidrIp: !Ref PrivateSubnet2CIDR + - IpProtocol: tcp + FromPort: 8081 + ToPort: 8081 + CidrIp: !Ref PrivateSubnet1CIDR + - IpProtocol: tcp + FromPort: 8081 + ToPort: 8081 + CidrIp: !Ref PrivateSubnet2CIDR + ArtifactoryECSBuild: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-ecs-ec2.template.yaml' + Parameters: + PrivateSubnet1ID: !Ref PrivateSubnet1ID + PrivateSubnet2ID: !Ref PrivateSubnet2ID + ClusterName: !Ref ClusterName + CreateNewECSCluster: !Ref CreateNewECSCluster + MinScalingNodes: !Ref NumberOfEC2Nodes + MaxScalingNodes: !Ref NumberOfEC2Nodes + KeyPairName: !Ref KeyPairName + InstanceType: !Ref InstanceType + VolumeSize: !Ref VolumeSize + DeploymentTag: Artifactory + NumberOfSecondary: !Ref NumberOfSecondary + ArtifactoryLicense1: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense1}}' + ArtifactoryLicense2: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense2}}' + ArtifactoryLicense3: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense3}}' + ArtifactoryLicense4: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense4}}' + CertificateDomain: !Ref CertificateDomain + ArtifactoryServerName: !Ref ArtifactoryServerName + ArtifactoryIAMAcessKey: !GetAtt ArtifactoryCoreInfraStack.Outputs.IAMAcessKey + SecretAccessKey: !GetAtt ArtifactoryCoreInfraStack.Outputs.SecretAccessKey + ArtifactoryS3Bucket: !GetAtt ArtifactoryCoreInfraStack.Outputs.S3Bucket + ArtifactoryDBEndpointAddress: !GetAtt ArtifactoryCoreInfraStack.Outputs.ArtifactoryDBEndpointAddress + CertificateKey: !Ref CertificateKey + Certificate: !Ref Certificate + DBType: mysql + DatabaseName: !Ref DatabaseName + DatabaseUser: !Ref DatabaseUser + DatabasePassword: !Ref DatabasePassword + MasterKey: !Ref MasterKey + ExtraJavaOptions: !Ref ExtraJavaOptions + ArtifactoryVersion: !Ref ArtifactoryVersion + SecurityGroups: !Ref ArtifactoryEC2SG + ArtifactoryTargetGroupArn: !Ref ArtifactoryTargetGroup + AnsibleVaultPass: !Ref AnsibleVaultPass + QSS3BucketName: !Ref QSS3BucketName + QSS3KeyPrefix: !Ref QSS3KeyPrefix + +Outputs: + ArtifactoryUrl: + Description: URL of the ELB to access Artifactory + Value: !Sub "https://${ArtifactoryELB.DNSName}" + BastionIP: + Value: !If + - EnableBastion + - !GetAtt BastionStack.Outputs.EIP1 + - "" diff --git a/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-master.template.yaml b/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-master.template.yaml new file mode 100755 index 0000000..da87f8f --- /dev/null +++ b/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs-master.template.yaml @@ -0,0 +1,541 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: 'JFrog Artifactory Quick Start Deployment' +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Security configuration + Parameters: + - KeyPairName + - AccessCIDR + - RemoteAccessCIDR + - Label: + default: Network configuration + Parameters: + - AvailabilityZones + - VPCCIDR + - PrivateSubnet1CIDR + - PrivateSubnet2CIDR + - PublicSubnet1CIDR + - PublicSubnet2CIDR + - Label: + default: Bastion configuration + Parameters: + - ProvisionBastionHost + - BastionInstanceType + - BastionOS + - BastionRootVolumeSize + - BastionEnableTCPForwarding + - NumBastionHosts + - BastionEnableX11Forwarding + - Label: + default: ECS configuration + Parameters: + - ClusterName + - InstanceType + - VolumeSize + - Label: + default: JFrog Artifactory configuration + Parameters: + - ArtifactoryVersion + - NumberOfSecondary + - NumberOfEC2Nodes + - SMLicensesName + - Certificate + - CertificateKey + - CertificateDomain + - ArtifactoryServerName + - MasterKey + - ExtraJavaOptions + - AnsibleVaultPass + - Label: + default: Amazon RDS Configuration + Parameters: + - DatabaseName + - DatabaseEngine + - DatabaseVersion + - DatabaseUser + - DatabasePassword + - DatabaseInstance + - DBAllocatedStorage + - MultiAZDatabase + - Label: + default: AWS Quick Start Configuration + Parameters: + - QSS3BucketName + - QSS3KeyPrefix + ParameterLabels: + KeyPairName: + default: SSH key name + AccessCIDR: + default: Permitted IP range + RemoteAccessCIDR: + default: Remote access CIDR + AvailabilityZones: + default: Availability Zones + VPCCIDR: + default: VPC CIDR + PrivateSubnet1CIDR: + default: Private subnet 1 CIDR + PrivateSubnet2CIDR: + default: Private subnet 2 CIDR + PublicSubnet1CIDR: + default: Public subnet 1 CIDR + PublicSubnet2CIDR: + default: Public subnet 2 CIDR + ProvisionBastionHost: + default: Bastion instance + BastionInstanceType: + default: Bastion instance type + BastionRootVolumeSize: + default: Bastion root volume size + BastionEnableTCPForwarding: + default: Bastion enable TCP forwarding + BastionEnableX11Forwarding: + default: Bastion enable X11 forwarding + BastionOS: + default: Bastion operating system + NumBastionHosts: + default: Number of bastion instances + ArtifactoryVersion: + default: Artifactory version + NumberOfSecondary: + default: Number of secondary instances + NumberOfEC2Nodes: + default: Number of EC2 nodes + ClusterName: + default: ECS cluster name + InstanceType: + default: EC2 instance type + VolumeSize: + default: EBS Root volume size + SMLicensesName: + default: Artifactory licenses secret name + Certificate: + default: Certificate + CertificateKey: + default: Certificate key + CertificateDomain: + default: Certificate domain + ArtifactoryServerName: + default: Artifactory server name + MasterKey: + default: Master server key + ExtraJavaOptions: + default: Extra Java options + AnsibleVaultPass: + Description: Ansiblevault Password to secure the artifactory.yml + Type: String + NoEcho: 'true' + DatabaseName: + default: Database name + DatabaseEngine: + default: Database negine + DatabaseVersion: + default: Database version + DatabaseUser: + default: Database user + DatabasePassword: + default: Database password + DatabaseInstance: + default: Database instance type + DBAllocatedStorage: + default: Database allocated storage + MultiAZDatabase: + default: High available database + QSS3BucketName: + default: Quick Start S3 bucket name + QSS3KeyPrefix: + default: Quick Start S3 key prefix +Parameters: + KeyPairName: + Description: The name of an existing public/private key pair, which allows you + to securely connect to your instance after it launches. + Type: AWS::EC2::KeyPair::KeyName + AccessCIDR: + Description: The CIDR IP range that is permitted to access Artifactory. + We recommend that you set this value to a trusted IP range. + For example, you might want to grant only your corporate network access to the software. + 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ + Type: String + RemoteAccessCIDR: + Description: The remote CIDR range for allowing SSH into the Bastion instance. + We recommend that you set this value to a trusted IP range. + For example, you might want to grant specific ranges inside your corporate network SSH access. + 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ + Type: String + AvailabilityZones: + Description: The list of Availability Zones to use for the subnets in the VPC. Two + Availability Zones are used for this deployment, and the logical order of your + selections is preserved. + Default: us-west-2a, us-west-1b + Type: List + VPCCIDR: + Description: The CIDR block for the VPC. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.0.0/16 + Type: String + PrivateSubnet1CIDR: + Description: The CIDR block for private subnet 1 located in Availability Zone 1. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.0.0/19 + Type: String + PrivateSubnet2CIDR: + Description: The CIDR block for private subnet 2 located in Availability Zone 2. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.32.0/19 + Type: String + PublicSubnet1CIDR: + Description: The CIDR block for the public (DMZ) subnet 1 located in Availability + Zone 1. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.128.0/20 + Type: String + PublicSubnet2CIDR: + Description: The CIDR block for the public (DMZ) subnet 2 located in Availability + Zone 2. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.144.0/20 + Type: String + ProvisionBastionHost: + Description: Choose Disabled to skip creating a bastion instance. Due to the Artifactory nodes being + created in private subnets, the default setting of Enabled this is highly recommended. + AllowedValues: + - "Enabled" + - "Disabled" + Default: "Enabled" + Type: String + BastionInstanceType: + Description: The size of the bastion instances. + AllowedValues: + - t2.nano + - t2.micro + - t2.small + - t2.medium + - t2.large + - m3.large + - m3.xlarge + - m3.2xlarge + - m4.large + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + Default: "t2.micro" + Type: String + BastionRootVolumeSize: + Description: The size of the root volume on the bastion instances. + Default: 10 + Type: Number + BastionEnableTCPForwarding: + Description: Choose whether to enable TCPForwarding via the bootstrapping of the bastion instance + or not. + AllowedValues: + - "true" + - "false" + Default: "true" + Type: String + BastionEnableX11Forwarding: + Description: Choose true to enable X11 via the bootstrapping of the bastion host. + Setting this value to true will enable X Windows over SSH. + X11 forwarding can be very useful but it is also a security risk, so we recommend + that you keep the default (false) setting unless required. + AllowedValues: + - "true" + - "false" + Default: "false" + Type: String + BastionOS: + Description: The Linux distribution for the Amazon Machine Image (AMI) to be used for the bastion instances. + AllowedValues: + - "Amazon-Linux-HVM" + - "CentOS-7-HVM" + - "Ubuntu-Server-14.04-LTS-HVM" + - "Ubuntu-Server-16.04-LTS-HVM" + - "SUSE-SLES-15-HVM" + Default: "Amazon-Linux-HVM" + Type: String + NumBastionHosts: + Description: The number of bastion instances to create. + AllowedValues: + - '1' + - '2' + - '3' + - '4' + Default: '1' + Type: String + ClusterName: + Description: The desired name for your ECS cluster. + Default: JFrog + Type: String + InstanceType: + Description: The EC2 instance type for the Artifactory Docker hosts. + AllowedValues: + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + - m4.10xlarge + ConstraintDescription: Must contain valid instance type + Default: m4.xlarge + Type: String + VolumeSize: + Description: The size in GB of the available storage; the Quick Start will create an + Amazon Elastic Block Store (Amazon EBS) volumes of this size. + Default: 200 + Type: Number + NumberOfEC2Nodes: + Description: The number of EC2 nodes to create for the ECS cluster. There must be + enough nodes to run the number of secondaries plus the primary task. + AllowedValues: + - 3 + - 4 + - 5 + - 6 + - 7 + - 8 + Default: 3 + Type: Number + NumberOfSecondary: + Description: The number of secondary Artifactory servers to complete your + HA deployment. To fit the Artifactory best practices, the minimum number + is two; the maximum is seven. Do not select more than instances than you + have licenses for. + AllowedValues: + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + Default: 2 + Type: Number + ArtifactoryVersion: + Description: The version of Artifactory that you want to deploy into the Quick Start. + Please see the release notes to select the version you want to deploy. + https://www.jfrog.com/confluence/display/RTF/Release+Notes + #AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ + #ConstraintDescription: A version that matches X.X.X per Artifactory releases. + Default: 6.15.0 + Type: String + SMLicensesName: + Description: The secret name created in AWS Secrets Manager which contains the Artifactory licenses. + Type: String + Certificate: + Description: The certificate file to be used to terminate SSL. + AllowedPattern: ^(-----BEGIN CERTIFICATE-----)\n(.*?\n)+(-----END CERTIFICATE-----)$ + ConstraintDescription: A Certificate that begins with "-----BEGIN CERTIFICATE----- " and ends with "-----END CERTIFICATE----- " + Type: String + CertificateKey: + Description: The private key for the certificate. + AllowedPattern: ^(-----BEGIN [A-Za-z ]+ KEY-----)\n(.*?\n)+(-----END [A-Za-z ]+ KEY-----)$ + ConstraintDescription: A Private key that begins with "-----BEGIN PRIVATE KEY-----" and ends with "-----END PRIVATE KEY-----" + NoEcho: 'true' + Type: String + CertificateDomain: + Description: The domain matching that of the certificate. Ensure that it matches your certificate. + AllowedPattern: ^[A-Za-z0-9]+[.A-Za-z0-9]+[A-Za-z0-9]$ + ConstraintDescription: The domain must not start or end with a '.' + Type: String + ArtifactoryServerName: + Description: The name of your Artifactory server. Ensure that this matches your certificate. + Type: String + MasterKey: + Description: The master key for the Artifactory cluster. Generate a master key by using the command '$openssl rand -hex 16'. + AllowedPattern: ^[a-zA-Z0-9]+$ + MinLength: '1' + MaxLength: '64' + ConstraintDescription: Only capital or lowercase letters and numbers, with a Max of 64 characters. + NoEcho: 'true' + Type: String + ExtraJavaOptions: + Description: Setting Java memory parameters for Artifactory. For more information, see the Artifactory + system requirements. + https://www.jfrog.com/confluence/display/RTF/System+Requirements#SystemRequirements-RecommendedHardware. + Default: -Xmx4g + Type: String + AnsibleVaultPass: + Description: The Ansible Vault password to protect the Artifactory YAML configuration file + generated during the Artifactory deployment. This YAML file is stored on the EC2 nodes + and secured with this password. + NoEcho: 'true' + Type: String + DatabaseName: + Description: The name for your DB instance. The name must be unique across all DB instances + owned by your AWS account in the current AWS Region. The DB instance identifier is case-insensitive, + but is stored as all lowercase (as in "mydbinstance"). + AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ + MinLength: '1' + MaxLength: '60' + ConstraintDescription: 1 to 60 alphanumeric characters First character must be a letter. + Default: artdb + Type: String + DatabaseEngine: + Description: The database engine that you want to run, currently locked to MySQL. + AllowedValues: + - MySQL + Default: MySQL + Type: String + DatabaseVersion: + Description: The major version of the MySQL database engine you want to run. This is currently locked to MySQL versions + supported by Artifactory and RDS. + AllowedValues: + - 5.5 + - 5.6 + - 5.7 + Default: 5.7 + Type: String + DatabaseUser: + Description: The login ID for the master user of your DB instance. + MinLength: '1' + MaxLength: '16' + AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ + ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter + Default: artifactory + Type: String + DatabasePassword: + Description: The password for the Artifactory database user. + AllowedPattern: ^[^ \\']+$ + MinLength: '8' + MaxLength: '12' + ConstraintDescription: Must be at least 8 and no more than + 12 characters containing letters and (minimum 1 capital letter), numbers and + symbols. + NoEcho: 'true' + Type: String + DatabaseInstance: + Description: The size of the database to be deployed as part of the Quick Start. + AllowedValues: + - db.m3.medium + - db.m3.large + - db.m3.xlarge + - db.m3.2xlarge + - db.m4.large + - db.m4.xlarge + - db.m4.2xlarge + - db.m4.10xlarge + - db.m4.16xlarge + - db.m5.large + - db.m5.xlarge + - db.m5.2xlarge + - db.m5.4xlarge + - db.m5.12xlarge + - db.m5.24xlarge + ConstraintDescription: Must be a valid database Instance Type. + Default: db.m4.large + Type: String + DBAllocatedStorage: + Description: The size in GB of the available storage for the database instance. + MinValue: 5 + MaxValue: 1024 + Default: 10 + Type: Number + MultiAZDatabase: + Description: Choose false to create an Amazon RDS instance in a single Availability Zone. + ConstraintDescription: True or False + AllowedValues: + - "true" + - "false" + Default: "true" + Type: String + QSS3BucketName: + Description: S3 bucket name for the Quick Start assets. This string can include + numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start + or end with a hyphen (-). + AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ + ConstraintDescription: Quick Start bucket name can include numbers, lowercase + letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen + (-). + Default: aws-quickstart + Type: String + QSS3KeyPrefix: + Description: S3 key prefix for the Quick Start assets. Quick Start key prefix + can include numbers, lowercase letters, uppercase letters, hyphens (-), and + forward slash (/). + AllowedPattern: ^[0-9a-zA-Z-/]*$ + ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, + uppercase letters, hyphens (-), and forward slash (/). + Default: quickstart-jfrog-artifactory/ + Type: String +Resources: + VPCStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: + Fn::Sub: https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template + Parameters: + AvailabilityZones: + Fn::Join: + - ',' + - Ref: AvailabilityZones + KeyPairName: + Ref: KeyPairName + NumberOfAZs: '2' + PrivateSubnet1ACIDR: + Ref: PrivateSubnet1CIDR + PrivateSubnet2ACIDR: + Ref: PrivateSubnet2CIDR + PublicSubnet1CIDR: + Ref: PublicSubnet1CIDR + PublicSubnet2CIDR: + Ref: PublicSubnet2CIDR + VPCCIDR: + Ref: VPCCIDR + ArtifactoryExistingVPCStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-ecs-existing-vpc.template.yaml' + Parameters: + KeyPairName: !Ref KeyPairName + VPCID: !GetAtt VPCStack.Outputs.VPCID + VPCCIDR: !Ref VPCCIDR + PublicSubnet1ID: !GetAtt VPCStack.Outputs.PublicSubnet1ID + PublicSubnet2ID: !GetAtt VPCStack.Outputs.PublicSubnet2ID + PrivateSubnet1ID: !GetAtt VPCStack.Outputs.PrivateSubnet1AID + PrivateSubnet2ID: !GetAtt VPCStack.Outputs.PrivateSubnet2AID + PrivateSubnet1CIDR: !Ref PrivateSubnet1CIDR + PrivateSubnet2CIDR: !Ref PrivateSubnet2CIDR + AccessCIDR: !Ref AccessCIDR + RemoteAccessCIDR: !Ref RemoteAccessCIDR + ProvisionBastionHost: !Ref ProvisionBastionHost + BastionInstanceType: !Ref BastionInstanceType + BastionRootVolumeSize: !Ref BastionRootVolumeSize + BastionEnableTCPForwarding: !Ref BastionEnableTCPForwarding + BastionEnableX11Forwarding: !Ref BastionEnableX11Forwarding + BastionOS: !Ref BastionOS + NumBastionHosts: !Ref NumBastionHosts + ClusterName: !Ref ClusterName + InstanceType: !Ref InstanceType + VolumeSize: !Ref VolumeSize + NumberOfSecondary: !Ref NumberOfSecondary + NumberOfEC2Nodes: !Ref NumberOfEC2Nodes + ArtifactoryVersion: !Ref ArtifactoryVersion + SMLicensesName: !Ref SMLicensesName + Certificate: !Ref Certificate + CertificateKey: !Ref CertificateKey + CertificateDomain: !Ref CertificateDomain + ArtifactoryServerName: !Ref ArtifactoryServerName + MasterKey: !Ref MasterKey + ExtraJavaOptions: !Ref ExtraJavaOptions + AnsibleVaultPass: !Ref AnsibleVaultPass + DatabaseName: !Ref DatabaseName + DatabaseEngine: !Ref DatabaseEngine + DatabaseVersion: !Ref DatabaseVersion + DatabaseUser: !Ref DatabaseUser + DatabasePassword: !Ref DatabasePassword + DatabaseInstance: !Ref DatabaseInstance + DBAllocatedStorage: !Ref DBAllocatedStorage + MultiAZDatabase: !Ref MultiAZDatabase + QSS3BucketName: !Ref QSS3BucketName + QSS3KeyPrefix: !Ref QSS3KeyPrefix + +Outputs: + ArtifactoryUrl: + Description: URL of the ELB to access Artifactory + Value: !Sub ${ArtifactoryExistingVPCStack.Outputs.ArtifactoryUrl} + BastionIP: + Value: !Sub ${ArtifactoryExistingVPCStack.Outputs.BastionIP} + Description: Bastion host IP, for admin access via SSH diff --git a/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs.template.yaml b/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs.template.yaml new file mode 100644 index 0000000..d041c51 --- /dev/null +++ b/CloudFormation-JCR-ECS/templates/jfrog-jcr6-ecs.template.yaml @@ -0,0 +1,183 @@ +AWSTemplateFormatVersion: "2010-09-09" +Description: "Deploys the ECS Artifactory Service and Task" +Parameters: + ECSCluster: + Type: String + ServiceName: + Type: String + ArtifactoryTargetGroupArn: + Type: String + ArtifactoryVersion: + Type: String + DBPlugin: + Type: String + MasterKey: + Type: String + NoEcho: 'true' + ExtraJavaOptions: + Type: String + ArtifactoryPrimary: + Type: String + NumberNodes: + Type: Number + DBType: + Type: String + DatabaseUser: + Type: String + DatabaseName: + Type: String + DatabasePassword: + Type: String + NoEcho: 'true' + ArtifactoryDBEndpointAddress: + Type: String + ECSRoleArn: + Type: String + ECSLogGroup: + Type: String +Resources: + ECSService: + Type: AWS::ECS::Service + Properties: + Cluster: !Ref ECSCluster + ServiceName: !Ref ServiceName + LaunchType: EC2 + DesiredCount: !Ref NumberNodes + LoadBalancers: + - ContainerName: nginx + ContainerPort: 443 + TargetGroupArn: !Ref ArtifactoryTargetGroupArn + TaskDefinition: + Ref: ArtifactoryTaskDefinition + HealthCheckGracePeriodSeconds: 300 + ArtifactoryTaskDefinition: + Type: AWS::ECS::TaskDefinition + Properties: + Cpu: "2048" + Family: !Sub ${ServiceName}-Task + Memory: "4096" + NetworkMode: bridge + RequiresCompatibilities: + - EC2 + ExecutionRoleArn: !Ref ECSRoleArn + Volumes: + - Name: etc + Host: + SourcePath: /data/jfrog/artifactory/etc/ + - Name: temp-plugins + Host: + SourcePath: /data/jfrog/artifactory/tmp/plugins + - Name: java-certs + Host: + SourcePath: /data/jfrog/artifactory/java_certs + - Name: plugins + Host: + SourcePath: !Sub + /data/jfrog/artifactory/plugins/${DBPlugin} + - Name: nginx + Host: + SourcePath: /data/jfrog/nginx + ContainerDefinitions: + - Name: artifactory + EntryPoint: + - /bin/bash + - "-c" + Command: + - "echo export HA_HOST_IP=`wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4` > /tmp/source; echo /entrypoint-artifactory.sh >> /tmp/source; chmod +x /tmp/source; /tmp/source" + Image: !Sub + docker.bintray.io/jfrog/artifactory-pro:${ArtifactoryVersion} + PortMappings: + - ContainerPort: 8081 + HostPort: 8081 + Protocol: tcp + MountPoints: + - ContainerPath: /artifactory_extra_conf + ReadOnly: False + SourceVolume: etc + - ContainerPath: /tmp/plugins + ReadOnly: False + SourceVolume: temp-plugins + - ContainerPath: /artifactory_extra_certs + ReadOnly: False + SourceVolume: java-certs + - ContainerPath: !Sub + /opt/jfrog/artifactory/tomcat/lib/${DBPlugin} + ReadOnly: False + SourceVolume: plugins + Ulimits: + - Name: nproc + SoftLimit: 65535 + HardLimit: 65535 + - Name: nofile + SoftLimit: 32000 + HardLimit: 40000 + HealthCheck: + Command: + - CMD-SHELL + - (printf 'GET / HTTP/1.0\r\n\r\n'; sleep 1) | nc 127.0.0.1 8081 | grep OK || exit 1 + Interval: 5 + Retries: 3 + StartPeriod: 60 + Timeout: 10 + Environment: + - Name: EXTRA_JAVA_OPTIONS + Value: !Ref ExtraJavaOptions + - Name: ARTIFACTORY_MASTER_KEY + Value: !Ref MasterKey + - Name: HA_IS_PRIMARY + Value: !Ref ArtifactoryPrimary + - Name: DB_URL + Value: !Sub + jdbc:mysql://${ArtifactoryDBEndpointAddress}:3306/${DatabaseName}?characterEncoding=UTF-8&elideSetAutoCommits=true&verifyServerCertificate=true&useSSL=false&requireSSL=false + - Name: DB_TYPE + Value: !Ref DBType + - Name: DB_USER + Value: !Ref DatabaseUser + - Name: DB_PASSWORD + Value: !Ref DatabasePassword + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-group: !Ref ECSLogGroup + awslogs-region: !Ref AWS::Region + awslogs-stream-prefix: artifactory + - Name: nginx + Image: !Sub + docker.bintray.io/jfrog/nginx-artifactory-pro:6.14.1 + PortMappings: + - ContainerPort: 80 + HostPort: 80 + Protocol: tcp + - ContainerPort: 443 + HostPort: 443 + Protocol: tcp + Essential: false + DependsOn: + - Condition: HEALTHY + ContainerName: artifactory + Links: + - artifactory:artifactory + MountPoints: + - ContainerPath: /var/opt/jfrog/nginx + ReadOnly: False + SourceVolume: nginx + Ulimits: + - Name: nproc + SoftLimit: 65535 + HardLimit: 65535 + - Name: nofile + SoftLimit: 32000 + HardLimit: 40000 + Environment: + - Name: ART_BASE_URL + Value: http://artifactory:8081/artifactory + - Name: SSL + Value: "true" + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-group: + Ref: ECSLogGroup + awslogs-region: + Ref: AWS::Region + awslogs-stream-prefix: nginx \ No newline at end of file diff --git a/CloudFormation-JCR-EKS/.gitmodules b/CloudFormation-JCR-EKS/.gitmodules new file mode 100644 index 0000000..940bc00 --- /dev/null +++ b/CloudFormation-JCR-EKS/.gitmodules @@ -0,0 +1,12 @@ +[submodule "submodules/quickstart-aws-vpc"] + path = submodules/quickstart-aws-vpc + url = https://github.com/aws-quickstart/quickstart-aws-vpc.git + branch = master +[submodule "submodules/quickstart-linux-bastion"] + path = submodules/quickstart-linux-bastion + url = https://github.com/aws-quickstart/quickstart-linux-bastion.git + branch = master +[submodule "submodules/quickstart-amazon-eks"] + path = submodules/quickstart-amazon-eks + url = https://github.com/aws-quickstart/quickstart-amazon-eks.git + branch = master diff --git a/CloudFormation-JCR-EKS/LICENSE.txt b/CloudFormation-JCR-EKS/LICENSE.txt new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/CloudFormation-JCR-EKS/LICENSE.txt @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/CloudFormation-JCR-EKS/Makefile b/CloudFormation-JCR-EKS/Makefile new file mode 100644 index 0000000..cc28cac --- /dev/null +++ b/CloudFormation-JCR-EKS/Makefile @@ -0,0 +1,34 @@ +.PHONY: help run submodules + +submodules: + git submodule init + git submodule update + cd submodules/quickstart-linux-bastion && git submodule init && git submodule update + cd submodules/quickstart-amazon-eks && git submodule init && git submodule update + +help: + @echo "make test : executes taskcat" + +create: + aws cloudformation create-stack --stack-name test --template-body file://$(pwd)/templates/jfrog-artifactory-ec2-new-vpc.template --parameters $(cat .ignore/params) --capabilities CAPABILITY_IAM + +delete: + aws cloudformation delete-stack --stack-name test + +.ONESHELL: +test: lint submodules + cd .. && pwd && taskcat -c theflash/ci/config.yml -n + +lint: + time taskcat -l -c ci/config.yml + +public_repo: + taskcat -c theflash/ci/config.yml -u + #https://taskcat-tag-quickstart-jfrog-artifactory-c2fa9d34.s3-us-west-2.amazonaws.com/quickstart-jfrog-artifactory/templates/jfrog-artifactory-ec2-master.template + #curl https://taskcat-tag-quickstart-jfrog-artifactory-7008506c.s3-us-west-2.amazonaws.com/quickstart-jfrog-artifactory/templates/jfrog-artifactory-ec2-master.template + +get_public_dns: + aws elb describe-load-balancers | jq '.LoadBalancerDescriptions[]| .CanonicalHostedZoneName' + +get_bastion_ip: + aws ec2 describe-instances | jq '.[] | select(.[].Instances[].Tags[].Value == "LinuxBastion") ' diff --git a/CloudFormation-JCR-EKS/README.md b/CloudFormation-JCR-EKS/README.md new file mode 100644 index 0000000..e69de29 diff --git a/CloudFormation-JCR-EKS/ci/jfrog-new-vpc-jcr6-eks.json b/CloudFormation-JCR-EKS/ci/jfrog-new-vpc-jcr6-eks.json new file mode 100755 index 0000000..87d9beb --- /dev/null +++ b/CloudFormation-JCR-EKS/ci/jfrog-new-vpc-jcr6-eks.json @@ -0,0 +1,70 @@ +[ + { + "ParameterKey": "KeyPairName", + "ParameterValue": "$[taskcat_getkeypair]" + }, + { + "ParameterKey": "RemoteAccessCIDR", + "ParameterValue": "10.0.0.0/16" + }, + { + "ParameterKey": "AccessCIDR", + "ParameterValue": "10.0.0.0/16" + }, + { + "ParameterKey": "AvailabilityZones", + "ParameterValue": "$[taskcat_genaz_3]" + }, + { + "ParameterKey": "DatabasePassword", + "ParameterValue": "$[taskcat_genpass_8A]" + }, + { + "ParameterKey": "QSS3BucketName", + "ParameterValue": "$[taskcat_autobucket]" + }, + { + "ParameterKey": "QSS3KeyPrefix", + "ParameterValue": "quickstart-jfrog-artifactory/" + }, + { + "ParameterKey": "SMLicensesName", + "ParameterValue": "jfrog-artifactory" + }, + { + "ParameterKey": "DatabaseInstance", + "ParameterValue": "db.t3.medium" + }, + { + "ParameterKey": "ArtifactoryVersion", + "ParameterValue": "6.15.0" + }, + { + "ParameterKey": "CertificateDomain", + "ParameterValue": "localdomain" + }, + { + "ParameterKey": "MasterKey", + "ParameterValue": "1ce2be4490ca2c662cb79636cf9b7b8e" + }, + { + "ParameterKey": "Certificate", + "ParameterValue": "-----BEGIN CERTIFICATE-----\nMIIFaDCCA1ACCQD45dB5tZFvCDANBgkqhkiG9w0BAQsFADB2MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCVN1bm55dmFsZTEOMAwGA1UECgwFSkZy\nb2cxFDASBgNVBAsMC0FydGlmYWN0b3J5MSAwHgYDVQQDDBdhcnRpZmFjdG9yeS5s\nb2NhbGRvbWFpbjAeFw0xOTA3MjMyMzE4MjVaFw0yMDA3MjIyMzE4MjVaMHYxCzAJ\nBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2YWxlMQ4wDAYD\nVQQKDAVKRnJvZzEUMBIGA1UECwwLQXJ0aWZhY3RvcnkxIDAeBgNVBAMMF2FydGlm\nYWN0b3J5LmxvY2FsZG9tYWluMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\nAgEA0b3OgTFKkNbXXHzPv3l9IqX7fFZcfS2ZMD4mBuNlGQ6kyyraeoKKiVdkOgQV\n/dwDxLeW6y+637J2KBiZTccHUS8/eC5ky9E6ECeFToCYsucUKRiWo9Uss6XS1N+Q\nKQHktCVYy+KFDkJIVEL6LFbUMLz0k1jOhI/FRveT8LQ9cZsfy8KIrCF92ErcdPSL\n02KO6RgaBjxRFtAw2ZdO07O9kcKBC5BpJdrEnJHalVJsJbZOqIuNjyKKp/8s9TtW\nEYhXAbz05RrdQ97Cse1a/rHR5EWL+ITRw3Q/mQUv/ilSrSxb+chtgGb0qdP7aV0h\nLOuxttQFFU2o62LHqnda6dWljxKpSYUz47ugCK0M4T2bRhy7lUgmZ3PcfZYLE2ue\nh1qIJfkDfi1WpbptJAs4MbgfTvF2FCAsh8tyFnl+TA5QBWLRcOF9y1qUAATa1JKX\nzKGf/5hExBRpuq371j4SLAb5qXYUuQqZiCe3O6qTx2Wo/jAOPV49wfK9D9fW5qmq\nND1Rpp8sKjlb2ixm7dhCWyWV+iGHpzX5tjBW35rikAisUoap47I1fNzYMiSTvbhv\n2+by2YY8jsiYRCRIAKzRbgOgDOXnYVtWFpLgUldMqWqo+X3LztYE8CxD0CQK5u12\nGxM5ztXKEaitCqUSjY34Gl4owukA9tzGnu09OuAYGkxVBO0CAwEAATANBgkqhkiG\n9w0BAQsFAAOCAgEATH4kyuKvZtq32b3I7yZ27Xp2yaxABs17g0jAzkv7o9GILo+3\ncVAJS2warQti+c+A2edjqEc97JXb6ul7/SHs7B9B0P4BZSUsI0byuPlQ45Kht891\njz3SF1o6jpKTniQPqsulMMshmYB6oY6CIyvKpaMaG3DypEXFmwEU7CdWr7oVISkn\npU6N6fI+V94Wzd1yHL8Jm/ixP4lqBAZqDhxNRq/Vok94wu2jvWwPIn2M+9myAiOs\nTSpcqLg8Vn70XkK5uuN1UXYU5QDo78GEZpOj7YfCxVjB43Ct/sEiu3iB0GzyEvq6\njlv07H9PyLjYeM7CuhZdgULBqEWbqNhO5XL/QJMYG06kXkT3GiWFP8pjnQRcJM4Z\nqQv8fOTDTuX5GumXKctXJwc7y9uywoIPwffEKlGuofWhihy8r/YXu2BgShDF3zYV\n1RAHVcWtPT5IqejpRZX5LdL4Hr2eCeUkcVCo7qqYLEwxFnQNG1nMrJJ2ewnlzPac\nJNNPRXgTDF3OkbON+3Wn/H0ndqIoqapHXSlkR54Stsk9yjHuaJ9TCANw2mxMDzf0\nRGw9ecirjpzQdP9jT/zK9X4kqFc0T3P6qN3X3s/OPPbroassRk/eqI/oMS6lNcQm\ny+SvRUrdtzKgmAfVE5yMLTVG0cZM4gWJ35DZHHqWnrbFEg7C0NLzoYc6yeQ=\n-----END CERTIFICATE-----" + }, + { + "ParameterKey": "CertificateKey", + "ParameterValue": "-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDRvc6BMUqQ1tdc\nfM+/eX0ipft8Vlx9LZkwPiYG42UZDqTLKtp6goqJV2Q6BBX93APEt5brL7rfsnYo\nGJlNxwdRLz94LmTL0ToQJ4VOgJiy5xQpGJaj1SyzpdLU35ApAeS0JVjL4oUOQkhU\nQvosVtQwvPSTWM6Ej8VG95PwtD1xmx/LwoisIX3YStx09IvTYo7pGBoGPFEW0DDZ\nl07Ts72RwoELkGkl2sSckdqVUmwltk6oi42PIoqn/yz1O1YRiFcBvPTlGt1D3sKx\n7Vr+sdHkRYv4hNHDdD+ZBS/+KVKtLFv5yG2AZvSp0/tpXSEs67G21AUVTajrYseq\nd1rp1aWPEqlJhTPju6AIrQzhPZtGHLuVSCZnc9x9lgsTa56HWogl+QN+LValum0k\nCzgxuB9O8XYUICyHy3IWeX5MDlAFYtFw4X3LWpQABNrUkpfMoZ//mETEFGm6rfvW\nPhIsBvmpdhS5CpmIJ7c7qpPHZaj+MA49Xj3B8r0P19bmqao0PVGmnywqOVvaLGbt\n2EJbJZX6IYenNfm2MFbfmuKQCKxShqnjsjV83NgyJJO9uG/b5vLZhjyOyJhEJEgA\nrNFuA6AM5edhW1YWkuBSV0ypaqj5fcvO1gTwLEPQJArm7XYbEznO1coRqK0KpRKN\njfgaXijC6QD23Mae7T064BgaTFUE7QIDAQABAoICAAgKDnBFQ2Zp1bdl0VC1h2Zc\nllcduE3UAZsnxq1c6fMb7JUc/2LSvhyljOHsZitk04AmyVIacj9Ax+ahir7Acjda\naERjAtoNGvyjhyiLJU82LD+nAZ8l/KCmKn6eUxg/SlTdWZn3BMKXJ86TAqPQcDGu\nDHHZZZEPMbCWrMT9I53HJGDbBAIVBo3T0L9q4DEqBfBJTDYQ+cq2EClG826J5SpB\nGlEnJ+Cbkg2uSYKPtjV712f+cV6bJFVsIn0D2Tiy0SLv6zMc5H5Fe5D2WBaLGlB1\nmffcn22udwGWgVBspQ6eNKhOVmQljhs0VN6lAzCFmDo5xjga0e6zypNuH732wnG3\nrOoIs6Qo5FQT4fSRSdSANlWJ8cF1OPL7ll0CN1BGfNa304s/C+qNO9SgMn6gmp3G\nuXYSgILp5UraRvn/KYXXVf/IRYrg6bnJ1TcuKCWJPjtibFLmIZutPkOTNF3YSW4s\nUOfLFK8Ky4r0/H6Nzt1r/f9qPHqVG7ILPWP1fwpcq06Tb6wvrJ1xkW9f3JTiWLMi\njkDiuQTmDf1JOk/TslZ3Mj6JDYFdHgT3lZdSNHiRuGgQ278ax/waSRn5W0LXr5b5\ntdHOBqLKnq7l96Hj0IArcrgh1ocJw4pP9JFWGDV2zfG+HzTf6QGmWj6j1Vf/91VN\n75tJmgKjScdU/DX+hTQBAoIBAQDy1YVc5Xwr+JzBV+xMorzVdaZ9Fwpycoy7OPy2\nNjFk1XD/cSDDK7aTDd9v8HF8Kmw4kVtngIkP/kdY4Gdu1oP22f2wkKjXGFQaRWPl\nNNEDhC+f7tjvGbF702jhB0kFdn3f7fEWyr4j8FP4xUqOczF2tzPgKeTkfz+ckQ0m\nDgmjm3vcPb+ZDLDE7fBw0On/qZr9dCH0oBwl7CMWmKggzYQEKNBbJowBwIlwTmL6\nI8Xzj7CAcV9sIVboJb7jNQPOCzHJA9bTGf5LMbD6X6D6Avlvd1J74/fFWkLME6CI\n0mlF5aOW2qKMo57DtnnEEKCL/6DXPfRvX6CuwbHqS5SIbwnxAoIBAQDdHPfDcpjU\n51KgFe4WoygNGVI604Aqv4ZnumJ4oshS71KqQidXgGBch9fDUad1txbDkeOHFW4u\nYwT67VsHeP7jbCA1Rn7MY8DASlSdJkZ7e4trUh1xfYH5tJK3i5hXMPu221sc7l5z\nNTKlohn00tIjy0adehk5oIyr1w1l9DtX6TMK2uNa7Z79mYFZLhrWRX6a93M4MA+J\nTq0bKF8j+x8RG2VZF6mom4XkHLOhYC9osG4xbj8AbhKBt9XrUcu+TT9Ct/kE7b54\ncvWtyf19cwviApebfQIn31pwieUaSncztSHdARCgVETP1334yOtrgKWb3CifaQHH\n0N+BqsrJR469AoIBAHAufAHCcm7N13zqZVuyApKKW3OGZWkhyinj1btHpeHzSNR5\nKq1/UET3L7XC2mqGHqCzZgqWsrsUuVkxshbeOvCbHDupWJalwpSwYcnNcJGzS10T\nNlye/gM6U0VB3FYNu3Drt2jUGKr5p5FRc3QDe2JgmDKCqB93OafWysA90+4lMj84\nt365AiC321AC81cMv3E/aUBdhyNtx3f05hbhWo+hW0AAusVEcTnUvJzaUeSHCP8N\nYQvPCxsL9Pd50lwph8JZZ7D2XSfXuO6xpuhY32rDMPPTCO+/FwS4PH141vFXeQ+D\nyXw3Sm0Xq4EMPV7vpRpKoNWi09Rn3w1iBShSQ8ECggEBAK7l3flEaS1m+I1WK2jO\nj7ykvc14RJYLvwXHgWKI6EnpsgqonzPwgMhQT1PY/8v2EdSKTl4ojmm0u1i8bNeh\nVoSPn35kj6GeefXgFcPkZbYBCEvQvSdrLmdU9QSoL80wGrsOEaj1x9H7T1+CtGNa\nawwTG30u+ksB+qNmTNvLbzFfbZd1gocHFE7moFDpTiMU/0sW1pWoNnHWwMiNi4wL\ndAx1DhqFxBZxRlwkc9X/HiECBXemC8GMT6k5v8UOg0m5EoP0v82tPI9L55cbAh67\n5LdWc5NzM0RUwNXpzUWZh2ZoLSwCTqNzZKa+fo9OZiE3tkdtwtgtGFJ0noaTkSnb\nJ0UCggEAWh58mtJ9TdAZdtU7kkx1/3c91hxl+up8PTSS6BdFa8DXxt9iQq4r914c\nVbfdnzKH7K245alH2aOcdw/TrK0ulQOazGGX2E6pWJV/ndxaUM4beUDUYbTVec3O\niVFWQT/Kp4WQktHQIu0w2fZElgOo30X3eTFEx0bvAm9Or2PiR34JAB5yerrEuFWq\n+Y3oZVb1tzJgLrVqAE6ct/TwkzhLaehlzPFNQb1u5POe3aUHjr5gsZDkqZua3Ys2\nQhArEEmrhEqRBACPWKWb6fSc+ajYlhltLg2g3EMqL4arW/3hgI2KS0vdiPtMRDvQ\n2YpoPnf204ak0AcDNZX257FnjRltUg==\n-----END PRIVATE KEY-----" + }, + { + "ParameterKey": "CertificateDomain", + "ParameterValue": "localdomain" + }, + { + "ParameterKey": "PrivateRepoUsername", + "ParameterValue": "" + }, + { + "ParameterKey": "PrivateRepoApiKey", + "ParameterValue": "" + } +] diff --git a/CloudFormation-JCR-EKS/ci/taskcat.yml b/CloudFormation-JCR-EKS/ci/taskcat.yml new file mode 100755 index 0000000..53f1017 --- /dev/null +++ b/CloudFormation-JCR-EKS/ci/taskcat.yml @@ -0,0 +1,13 @@ +global: + marketplace-ami: false + owner: quickstart-eng@amazon.com + qsname: quickstart-jfrog-artifactory + regions: + - us-west-2 + reporting: true +tests: + jfrog-artifactory-jcr6-eks: + parameter_input: jfrog-new-vpc-jcr6-eks.json + template_file: jfrog-jcr6-eks-master.template.yaml + regions: + - us-west-2 diff --git a/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-core-workload.template.yaml b/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-core-workload.template.yaml new file mode 100755 index 0000000..8f15f43 --- /dev/null +++ b/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-core-workload.template.yaml @@ -0,0 +1,301 @@ +AWSTemplateFormatVersion: "2010-09-09" +Description: "Deploys Artifactory into an existing Kubernetes cluster" +Parameters: + KubeManifestLambdaArn: + Type: String + HelmLambdaArn: + Type: String + KubeConfigPath: + Type: String + KubeConfigKmsContext: + Type: String + KubeGetLambdaArn: + Type: String + NumberOfSecondary: + Type: Number + AccessCIDR: + Type: String + ArtifactoryLicense1: + Type: String + ArtifactoryLicense2: + Type: String + ArtifactoryLicense3: + Type: String + ArtifactoryLicense4: + Type: String + ArtifactoryIAMAcessKey: + Type: String + NoEcho: 'true' + SecretAccessKey: + Type: String + NoEcho: 'true' + ArtifactoryS3Bucket: + Type: String + CertificateKey: + Type: String + NoEcho: 'true' + Certificate: + Type: String + CertificateDomain: + Type: String + PrivateRepoUsername: + NoEcho: 'true' + Type: String + PrivateRepoApiKey: + NoEcho: 'true' + Type: String + ArtifactoryDBEndpointAddress: + Type: String + DatabaseName: + Type: String + NoEcho: 'true' + DatabaseUser: + Type: String + DatabasePassword: + Type: String + NoEcho: 'true' + MasterKey: + Type: String + NoEcho: 'true' + ArtifactoryVersion: + Type: String + ArtifactoryDeploymentSize: + Type: String +Mappings: + DeploymentSize: + Large: + requestsMem: "6Gi" + requestsCpu: "4" + limitsMem: "10Gi" + limitsCpu: "8" + javaOptsXms: "6g" + javaOptsXmx: "8g" + Medium: + requestsMem: "4Gi" + requestsCpu: "2" + limitsMem: "8Gi" + limitsCpu: "6" + javaOptsXms: "4g" + javaOptsXmx: "6g" + Small: + requestsMem: "4Gi" + requestsCpu: "2" + limitsMem: "6Gi" + limitsCpu: "4" + javaOptsXms: "4g" + javaOptsXmx: "4g" +Resources: + NameSpace: + Type: "Custom::KubeManifest" + Version: '1.0' + Properties: + ServiceToken: !Ref KubeManifestLambdaArn + KubeConfigPath: !Ref KubeConfigPath + KubeConfigKmsContext: !Ref KubeConfigKmsContext + Manifest: + kind: Namespace + apiVersion: v1 + metadata: + name: jfrog-artifactory + labels: + app: artifactory + CertificateStore: + DependsOn: NameSpace + Type: "Custom::KubeManifest" + Version: '1.0' + Properties: + ServiceToken: !Ref KubeManifestLambdaArn + KubeConfigPath: !Ref KubeConfigPath + KubeConfigKmsContext: !Ref KubeConfigKmsContext + Manifest: + kind: Secret + apiVersion: v1 + metadata: + name: artifactory-nginx-tls + namespace: jfrog-artifactory + labels: + app: artifactory + chart: artifactory + type: kubernetes.io/tls + data: + tls.crt: + Fn::Base64: + !Sub "${Certificate}" + tls.key: + Fn::Base64: + !Sub "${CertificateKey}" + LicenseStore: + DependsOn: NameSpace + Type: "Custom::KubeManifest" + Version: '1.0' + Properties: + ServiceToken: !Ref KubeManifestLambdaArn + KubeConfigPath: !Ref KubeConfigPath + KubeConfigKmsContext: !Ref KubeConfigKmsContext + Manifest: + kind: Secret + apiVersion: v1 + metadata: + name: artifactory-cluster-license + namespace: jfrog-artifactory + labels: + app: artifactory + chart: artifactory + type: Opaque + stringData: + art.lic: !Sub + >- + ${ArtifactoryLicense1} + + + ${ArtifactoryLicense2} + + + ${ArtifactoryLicense3} + + + ${ArtifactoryLicense4} + ArtifactoryDeployment: + Type: "Custom::Helm" + DependsOn: + - LicenseStore + - CertificateStore + Version: '1.0' + Properties: + ServiceToken: !Ref HelmLambdaArn + KubeConfigPath: !Ref KubeConfigPath + KubeConfigKmsContext: !Ref KubeConfigKmsContext + Namespace: jfrog-artifactory + Name: quickstart-artifactory-ha + Chart: jfrog/artifactory-ha + RepoUrl: https://charts.jfrog.io + ValueYaml: !Sub + - | + artifactory: + name: artifactory-ha + image: + repository: docker.bintray.io/jfrog/artifactory-jcr + version: ${ArtifactoryVersion} + pullPolicy: Always + deleteDBPropertiesOnStartup: true + license: + secret: artifactory-cluster-license + dataKey: art.lic + masterKey: ${MasterKey} + preStartCommand: "wget -O /opt/jfrog/artifactory/tomcat/lib/mysql-connector-java-5.1.41.jar https://jcenter.bintray.com/mysql/mysql-connector-java/5.1.41/mysql-connector-java-5.1.41.jar" + persistence: + enabled: false + type: aws-s3 + awsS3: + endpoint: s3.${AWS::Region}.amazonaws.com + region: ${AWS::Region} + identity: ${ArtifactoryIAMAcessKey} + credential: ${SecretAccessKey} + bucketName: ${ArtifactoryS3Bucket} + primary: + resources: + requests: + memory: "${requests_memory}" + cpu: "${requests_cpu}" + limits: + memory: "${limits_memory}" + cpu: "${limits_cpu}" + javaOpts: + xms: "${java_xms}" + xmx: "${java_xmx}" + nodeSelector: + partition: artifactory-primary + node: + replicaCount: ${NumberOfSecondary} + resources: + requests: + memory: "${requests_memory}" + cpu: "${requests_cpu}" + limits: + memory: "${limits_memory}" + cpu: "${limits_cpu}" + javaOpts: + xms: "${java_xms}" + xmx: "${java_xmx}" + nodeSelector: + partition: artifactory-secondary + ## Only used if "affinity" is empty + podAntiAffinity: + ## Valid values are "soft" or "hard"; any other value indicates no anti-affinity + type: "soft" + topologyKey: "kubernetes.io/hostname" + postgresql: + enabled: false + database: + type: mysql + url: jdbc:mysql://${ArtifactoryDBEndpointAddress}:3306/${DatabaseName}?characterEncoding=UTF-8&elideSetAutoCommits=true #&verifyServerCertificate=true&useSSL=true&requireSSL=true + user: ${DatabaseUser} + password: ${DatabasePassword} + nginx: + image: + repository: docker.bintray.io/jfrog/nginx-artifactory-pro + version: ${ArtifactoryVersion} + tlsSecretName: artifactory-nginx-tls + nodeSelector: + partition: artifactory-primary + service: + loadBalancerSourceRanges: [ "${AccessCIDR}" ] + artifactoryConf: | + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_certificate {{ .Values.nginx.persistence.mountPath }}/ssl/tls.crt; + ssl_certificate_key {{ .Values.nginx.persistence.mountPath }}/ssl/tls.key; + ssl_session_cache shared:SSL:1m; + ssl_prefer_server_ciphers on; + ## server configuration + server { + listen {{ .Values.nginx.internalPortHttps }} ssl; + listen {{ .Values.nginx.internalPortHttp }} ; + server_name ~(?.+).${CertificateDomain} ~(?.+).jfrog.team + {{- range .Values.ingress.hosts -}} + {{- if contains "." . -}} + {{ "" | indent 0 }} ~(?.+)\.{{ . }} + {{- end -}} + {{- end -}}; + if ($http_x_forwarded_proto = '') { + set $http_x_forwarded_proto $scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/$ /artifactory/webapp/ redirect; + rewrite ^/artifactory/?(/webapp)?$ /artifactory/webapp/ redirect; + rewrite ^/(v2)/(.*) /artifactory/$1/$2; + chunked_transfer_encoding on; + client_max_body_size 0; + location /artifactory/ { + proxy_read_timeout 2400; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass http://{{ include "artifactory-ha.fullname" . }}:{{ .Values.artifactory.externalPort }}/artifactory/; + proxy_set_header X-Artifactory-Override-Base-Url $http_x_forwarded_proto://$host:$server_port/artifactory; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + } + - { requests_memory: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, requestsMem], + requests_cpu: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, requestsCpu], + limits_memory: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, limitsMem ], + limits_cpu: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, limitsCpu ], + java_xms: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, javaOptsXms ], + java_xmx: !FindInMap [DeploymentSize, !Ref ArtifactoryDeploymentSize, javaOptsXmx ] } + IngressHostName: + DependsOn: ArtifactoryDeployment + Type: "Custom::KubeGet" + Version: '1.0' + Properties: + ServiceToken: !Ref KubeGetLambdaArn + KubeConfigPath: !Ref KubeConfigPath + KubeConfigKmsContext: !Ref KubeConfigKmsContext + Namespace: jfrog-artifactory + Name: svc/quickstart-artifactory-ha-nginx + JsonPath: '{.status.loadBalancer.ingress[0].hostname}' +Outputs: + ArtifactoryUrl: + Value: !Sub https://${IngressHostName} \ No newline at end of file diff --git a/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-existing-vpc.template.yaml b/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-existing-vpc.template.yaml new file mode 100755 index 0000000..d443802 --- /dev/null +++ b/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-existing-vpc.template.yaml @@ -0,0 +1,663 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: Deploys an EKS cluster with JFrog Artifactory into an existing VPC (qs-1q037efm3). +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Security configuration + Parameters: + - KeyPairName + - AccessCIDR + - RemoteAccessCIDR + - AdditionalEKSAdminArns + - KubeConfigKmsContext + - Label: + default: Network configuration + Parameters: + - VPCID + - VPCCIDR + - PrivateSubnet1ID + - PrivateSubnet2ID + - PrivateSubnet3ID + - PublicSubnet1ID + - PublicSubnet2ID + - PublicSubnet3ID + - PrivateSubnet1CIDR + - PrivateSubnet2CIDR + - PrivateSubnet3CIDR + - Label: + default: Bastion configuration + Parameters: + - ProvisionBastionHost + - BastionInstanceType + - BastionOS + - BastionRootVolumeSize + - BastionEnableTCPForwarding + - BastionEnableX11Forwarding + - Label: + default: JFrog Artifactory configuration + Parameters: + - ArtifactoryVersion + - ArtifactoryDeploymentSize + - NumberOfSecondary + - SMLicensesName + - Certificate + - CertificateKey + - CertificateDomain + - MasterKey + - PrivateRepoUsername + - PrivateRepoApiKey + - Label: + default: Amazon RDS configuration + Parameters: + - DatabaseName + - DatabaseEngine + - DatabaseVersion + - DatabaseUser + - DatabasePassword + - DatabaseInstance + - DBAllocatedStorage + - MultiAZDatabase + - Label: + default: EC2/EKS configuration + Parameters: + - KubernetesVersion + - NodeInstanceType + - NumofSecondaryNodes + - NodeVolumeSize + - Label: + default: AWS Quick Start configuration + Parameters: + - QSS3BucketName + - QSS3KeyPrefix + - LambdaZipsBucketName + ParameterLabels: + KeyPairName: + default: SSH key name + AccessCIDR: + default: Permitted IP range + RemoteAccessCIDR: + default: Remote access CIDR + AdditionalEKSAdminArns: + default: Additional EKS admin ARNs + KubeConfigKmsContext: + default: Kubernetes config KMS context + VPCID: + default: VPC ID + VPCCIDR: + default: VPC CIDR + PublicSubnet1ID: + default: Public subnet 1 ID + PublicSubnet2ID: + default: Public subnet 2 ID + PublicSubnet3ID: + default: Public subnet 3 ID + PrivateSubnet1ID: + default: Private subnet 1 ID + PrivateSubnet2ID: + default: Private subnet 2 ID + PrivateSubnet3ID: + default: Private subnet 3 ID + PrivateSubnet1CIDR: + default: Private subnet 1 CIDR + PrivateSubnet2CIDR: + default: Private subnet 2 CIDR + PrivateSubnet3CIDR: + default: Private subnet 3 CIDR + ProvisionBastionHost: + default: Bastion instance + BastionInstanceType: + default: Bastion instance type + BastionRootVolumeSize: + default: Bastion root volume size + BastionEnableTCPForwarding: + default: Bastion enable TCP forwarding + BastionEnableX11Forwarding: + default: Bastion enable X11 forwarding + BastionOS: + default: Bastion operating system + ArtifactoryVersion: + default: Artifactory version + ArtifactoryDeploymentSize: + default: Artifactory deployment size + NumberOfSecondary: + default: Number of secondary pods + SMLicensesName: + default: Artifactory licenses secret name + Certificate: + default: Certificate + CertificateKey: + default: Certificate key + CertificateDomain: + default: Certificate domain + PrivateRepoUsername: + default: Username to include for private RPM repository + PrivateRepoApiKey: + default: Api Key for private RPM repository + MasterKey: + default: Master server key + DatabaseName: + default: Database name + DatabaseEngine: + default: Database engine + DatabaseVersion: + default: Database version + DatabaseUser: + default: Database user + DatabasePassword: + default: Database password + DatabaseInstance: + default: Database instance type + DBAllocatedStorage: + default: Database allocated storage + MultiAZDatabase: + default: High available database + NodeInstanceType: + default: Node instance type + NodeVolumeSize: + default: Node EBS volume size + NumofSecondaryNodes: + default: Number of secondary nodes + KubernetesVersion: + default: Kubernetes version + QSS3BucketName: + default: Quick Start S3 bucket name + QSS3KeyPrefix: + default: Quick Start S3 key prefix + LambdaZipsBucketName: + default: Lambda zips bucket name +Parameters: + KeyPairName: + Description: The name of an existing public/private key pair, which allows you + to securely connect to your instance after it launches. + Type: AWS::EC2::KeyPair::KeyName + AccessCIDR: + Description: The CIDR IP range that is permitted to access Artifactory. + We recommend that you set this value to a trusted IP range. + For example, you might want to grant only your corporate network access to the software. + 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ + Type: String + RemoteAccessCIDR: + Description: + The remote CIDR range for allowing SSH into the Bastion instance. + We recommend that you set this value to a trusted IP range. + For example, you might want to grant specific ranges inside your corporate network SSH access. + 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x + Type: String + AdditionalEKSAdminArns: + Description: '[OPTIONAL] The Amazon Resource Names (ARNs): a comma-separated list of IAM users and roles to be granted admin access to the EKS cluster.' + Default: "" + Type: CommaDelimitedList + KubeConfigKmsContext: + Description: String value used by KMS to encrypt/decrypt Kubernetes configuration file. + Default: "JFrogArtifactory" + Type: String + VPCID: + Description: The ID of your existing VPC for deployment (e.g., vpc-0343606e). + Type: AWS::EC2::VPC::Id + VPCCIDR: + Description: The CIDR block for the VPC. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.0.0/16 + Type: String + PublicSubnet1ID: + Description: The ID of the public subnet in Availability Zone 1 in your existing VPC (e.g., subnet-z0376dab). + Type: "AWS::EC2::Subnet::Id" + PublicSubnet2ID: + Description: The ID of the public subnet in Availability Zone 2 in your existing VPC (e.g., subnet-a29c3d84). + Type: "AWS::EC2::Subnet::Id" + PublicSubnet3ID: + Description: The ID of the public subnet in Availability Zone 3 in your existing VPC (e.g., subnet-a29c3d84). + Type: "AWS::EC2::Subnet::Id" + PrivateSubnet1ID: + Description: The ID of the private subnet in Availability Zone 1 in your existing VPC (e.g., subnet-a0246dcd). + Type: "AWS::EC2::Subnet::Id" + PrivateSubnet2ID: + Description: The ID of the private subnet in Availability Zone 2 in your existing VPC (e.g., subnet-b58c3d67). + Type: "AWS::EC2::Subnet::Id" + PrivateSubnet3ID: + Description: The ID of the private subnet in Availability Zone 3 in your existing VPC (e.g., subnet-b58c3d67). + Type: "AWS::EC2::Subnet::Id" + PrivateSubnet1CIDR: + Description: The CIDR of the private subnet in Availability Zone 1 in your existing VPC (e.g., 10.0.0.0/19). + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.0.0/19 + Type: String + PrivateSubnet2CIDR: + Description: The CIDR of the private subnet in Availability Zone 2 in your existing VPC (e.g., 10.0.32.0/19). + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.32.0/19 + Type: String + PrivateSubnet3CIDR: + Description: The CIDR block for private subnet 3 located in Availability Zone 3 in your existing VPC (e.g., 10.0.64.0/19). + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.64.0/19 + Type: String + NodeInstanceType: + Description: The Amazon EC2 instance type for the nodes hosting the Kubernetes pods. + AllowedValues: + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + - m4.10xlarge + ConstraintDescription: Must be a valid EC2 instance type + Default: m4.xlarge + Type: String + NodeVolumeSize: + Description: The size of EBS volumes for master node instances, in GB. + Default: 200 + Type: String + NumofSecondaryNodes: + Description: The initial number of secondary node instances to create. + If you do not have large enough instances to boot the number of secondary pods, the deployment will fail. + AllowedValues: + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + Default: 2 + Type: Number + KubernetesVersion: + Description: The Kubernetes control plane version. + AllowedValues: [ "1.13", "1.12", "1.11" ] + Default: "1.13" + Type: String + ProvisionBastionHost: + Description: Choose Disabled to skip creating a bastion instance. Due to the Artifactory nodes being + created in private subnets, the default setting of Enabled this is highly recommended. + AllowedValues: + - "Enabled" + - "Disabled" + Default: "Enabled" + Type: String + BastionInstanceType: + Description: The size of the bastion instances. + AllowedValues: + - t2.nano + - t2.micro + - t2.small + - t2.medium + - t2.large + - m3.large + - m3.xlarge + - m3.2xlarge + - m4.large + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + Default: "t2.micro" + Type: String + BastionRootVolumeSize: + Description: The size of the root volume on the bastion instances. + Default: 10 + Type: Number + BastionEnableTCPForwarding: + Description: Choose whether to enable TCPForwarding via the bootstrapping of the bastion instance + or not. + AllowedValues: + - "true" + - "false" + Default: "true" + Type: String + BastionEnableX11Forwarding: + Description: Choose true to enable X11 via the bootstrapping of the bastion host. + Setting this value to true will enable X Windows over SSH. + X11 forwarding can be very useful but it is also a security risk, so we recommend + that you keep the default (false) setting unless required. + AllowedValues: + - "true" + - "false" + Default: "false" + Type: String + BastionOS: + Description: The Linux distribution for the Amazon Machine Image (AMI) to be used for the bastion instances. + AllowedValues: + - "Amazon-Linux-HVM" + - "CentOS-7-HVM" + - "Ubuntu-Server-14.04-LTS-HVM" + - "Ubuntu-Server-16.04-LTS-HVM" + - "SUSE-SLES-15-HVM" + Default: "Amazon-Linux-HVM" + Type: String + NumberOfSecondary: + Description: Number of secondary Artifactory pods to complete your HA deployment. + Minimum number of 2 to fit the Artifactory best practices. Do not select more than + you license for. + AllowedValues: + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + Default: 2 + Type: Number + ArtifactoryVersion: + Description: The version of Artifactory that you want to deploy into the Quick Start. + Please see the release notes to select the version you want to deploy. + https://www.jfrog.com/confluence/display/RTF/Release+Notes + #AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ + #ConstraintDescription: A version that matches X.X.X per Artifactory releases. + Default: 6.15.0 + Type: String + ArtifactoryDeploymentSize: + Description: Configuration settings implemented by the Helm chart. There are currently three supported sizes. + 'Large:' Memory request of 6 GiB, memory limit of 10GiB; CPU request of 4, CPU limit of 8; Java heap size minimum of 6 GB, maximum of 8 GB. + 'Medium:' Memory request of 4 GiB, memory limit of 8 GiB; CPU request of 2, CPU limit of 6; Java heap size minimum of 4 GB, maximum of 6 GB. + 'Small:' Memory request of 4 GiB, memory limit of 6 GiB; CPU request of 2, CPU limit of 4; Java heap size of 4 GB. + AllowedValues: + - Small + - Medium + - Large + Default: Medium + Type: String + SMLicensesName: + Description: The secret name created in AWS Secrets Manager which contains the Artifactory licenses. + Type: String + Certificate: + Description: The certificate file to be used to terminate SSL. + AllowedPattern: ^(-----BEGIN CERTIFICATE-----)\n(.*?\n)+(-----END CERTIFICATE-----)$ + ConstraintDescription: A Certificate that begins with "-----BEGIN CERTIFICATE----- " and ends with "-----END CERTIFICATE----- " + Type: String + CertificateKey: + Description: The private key for the certificate. + AllowedPattern: ^(-----BEGIN [A-Za-z ]+ KEY-----)\n(.*?\n)+(-----END [A-Za-z ]+ KEY-----)$ + ConstraintDescription: A Private key that begins with "-----BEGIN PRIVATE KEY-----" and ends with "-----END PRIVATE KEY-----" + NoEcho: 'true' + Type: String + CertificateDomain: + Description: The domain matching that of the certificate. Ensure that it matches your certificate. + AllowedPattern: ^[A-Za-z0-9]+[.A-Za-z0-9]+[A-Za-z0-9]$ + ConstraintDescription: The domain must not start or end with a '.' + Type: String + PrivateRepoUsername: + Description: Username to include for private RPM repository + NoEcho: 'true' + Type: String + PrivateRepoApiKey: + Description: Api Key for private RPM repository + NoEcho: 'true' + Type: String + MasterKey: + Description: The master key for the Artifactory cluster. Generate a master key by using the command '$openssl rand -hex 16'. + AllowedPattern: ^[a-zA-Z0-9]+$ + MinLength: '1' + MaxLength: '64' + ConstraintDescription: Only capital or lowercase letters and numbers, with a Max of 64 characters. + NoEcho: 'true' + Type: String + DatabaseName: + Description: The name for your DB instance. The name must be unique across all DB instances + owned by your AWS account in the current AWS Region. The DB instance identifier is case-insensitive, + but is stored as all lowercase (as in "mydbinstance"). + AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ + MinLength: '1' + MaxLength: '60' + ConstraintDescription: 1 to 60 alphanumeric characters First character must be a letter. + Default: artdb + Type: String + DatabaseEngine: + Description: The database engine that you want to run, currently locked to MySQL. + AllowedValues: + - MySQL + Default: MySQL + Type: String + DatabaseVersion: + Description: The major version of the MySQL database engine you want to run. This is currently locked to MySQL versions + supported by Artifactory and RDS. + AllowedValues: + - 5.5 + - 5.6 + - 5.7 + Default: 5.7 + Type: String + DatabaseUser: + Description: The login ID for the master user of your DB instance. + MinLength: '1' + MaxLength: '16' + AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ + ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter + Default: artifactory + Type: String + DatabasePassword: + Description: The password for the Artifactory database user. + AllowedPattern: ^[^ \\']+$ + MinLength: '8' + MaxLength: '12' + ConstraintDescription: Must be at least 8 and no more than + 12 characters containing letters and (minimum 1 capital letter), numbers and + symbols. + NoEcho: 'true' + Type: String + DatabaseInstance: + Description: The size of the database to be deployed as part of the Quick Start. + AllowedValues: + - db.t3.medium + - db.m3.medium + - db.m3.large + - db.m3.xlarge + - db.m3.2xlarge + - db.m4.large + - db.m4.xlarge + - db.m4.2xlarge + - db.m4.10xlarge + - db.m4.16xlarge + - db.m5.large + - db.m5.xlarge + - db.m5.2xlarge + - db.m5.4xlarge + - db.m5.12xlarge + - db.m5.24xlarge + ConstraintDescription: Must be a valid database Instance Type. + Default: db.t3.medium + Type: String + DBAllocatedStorage: + Description: The size in GB of the available storage for the database instance. + MinValue: 5 + MaxValue: 1024 + Default: 10 + Type: Number + MultiAZDatabase: + Description: Choose false to create an Amazon RDS instance in a single Availability Zone. + ConstraintDescription: True or False + AllowedValues: + - "true" + - "false" + Default: "true" + Type: String + QSS3BucketName: + AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ + ConstraintDescription: + Quick Start bucket name can include numbers, lowercase + letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen + (-). + Default: aws-quickstart + Description: + S3 bucket name for the Quick Start assets. This string can include + numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start + or end with a hyphen (-). + Type: String + QSS3KeyPrefix: + AllowedPattern: ^[0-9a-zA-Z-/]*$ + ConstraintDescription: + Quick Start key prefix can include numbers, lowercase letters, + uppercase letters, hyphens (-), and forward slash (/). + Default: quickstart-jfrog-artifactory/ + Description: + S3 key prefix for the Quick Start assets. Quick Start key prefix + can include numbers, lowercase letters, uppercase letters, hyphens (-), and + forward slash (/). + Type: String + LambdaZipsBucketName: + Description: '[OPTIONAL] The name of the S3 bucket where the Lambda .zip + files should be placed. If you leave this parameter blank, an S3 bucket will be created.' + Default: '' + Type: String +Rules: + EKSSupport: + Assertions: + - AssertDescription: Your AWS Region does *NOT* yet support Amazon EKS + Assert: !Contains + - - us-west-2 + - us-east-1 + - us-east-2 + - eu-west-1 + - eu-west-2 + - eu-west-3 + - eu-north-1 + - eu-central-1 + - ap-southeast-1 + - ap-southeast-2 + - ap-northeast-1 + - ap-northeast-2 + - ap-south-1 + - !Ref 'AWS::Region' +Resources: + EKSStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub "https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-amazon-eks/templates/amazon-eks.template.yaml" + Parameters: + KeyPairName: !Ref KeyPairName + RemoteAccessCIDR: !Ref RemoteAccessCIDR + AdditionalEKSAdminArns: !Join [ ",", !Ref AdditionalEKSAdminArns ] + VPCID: !Ref VPCID + PrivateSubnet1ID: !Ref PrivateSubnet1ID + PrivateSubnet2ID: !Ref PrivateSubnet2ID + PrivateSubnet3ID: !Ref PrivateSubnet3ID + PublicSubnet1ID: !Ref PublicSubnet1ID + PublicSubnet2ID: !Ref PublicSubnet2ID + PublicSubnet3ID: !Ref PublicSubnet3ID + KubernetesVersion: !Ref KubernetesVersion + NodeInstanceType: !Ref NodeInstanceType + NumberOfNodes: '1' # 1 for the Artifactory master? + NodeGroupName: "artifactory-primary" + NodeVolumeSize: !Ref NodeVolumeSize + KubeConfigKmsContext: !Ref KubeConfigKmsContext + BootstrapArguments: "--kubelet-extra-args '--node-labels=partition=artifactory-primary'" + ProvisionBastionHost: !Ref ProvisionBastionHost + BastionInstanceType: !Ref BastionInstanceType + BastionOS: !Ref BastionOS + BastionRootVolumeSize: !Ref BastionRootVolumeSize + BastionEnableTCPForwarding: !Ref BastionEnableTCPForwarding + BastionEnableX11Forwarding: !Ref BastionEnableX11Forwarding + QSS3BucketName: !Ref QSS3BucketName + QSS3KeyPrefix: !Sub "${QSS3KeyPrefix}submodules/quickstart-amazon-eks/" + LambdaZipsBucketName: !Ref LambdaZipsBucketName + ArtifactorySecondaryNodesStack: + Type: "AWS::CloudFormation::Stack" + Properties: + TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-amazon-eks/templates/amazon-eks-nodegroup.template.yaml' + Parameters: + KeyPairName: !Ref KeyPairName + PrivateSubnet1ID: !Ref PrivateSubnet1ID + PrivateSubnet2ID: !Ref PrivateSubnet2ID + PrivateSubnet3ID: !Ref PrivateSubnet3ID + VPCID: !Ref VPCID + NodeInstanceType: !Ref NodeInstanceType + NumberOfNodes: !Ref NumofSecondaryNodes + NodeGroupName: "artifactory-secondary" + NodeVolumeSize: !Ref NodeVolumeSize + EKSControlPlane: !GetAtt EKSStack.Outputs.EKSClusterName + ControlPlaneSecurityGroup: !GetAtt EKSStack.Outputs.ControlPlaneSecurityGroup + NodeInstanceProfile: !GetAtt EKSStack.Outputs.NodeInstanceProfile + NodeInstanceRoleName: !GetAtt EKSStack.Outputs.NodeInstanceRoleName + KubernetesVersion: !Ref KubernetesVersion + BootstrapArguments: "--kubelet-extra-args '--node-labels=partition=artifactory-secondary'" + # Allow the bastion host to SSH into the secondary node pools + BastionToRegularIngress: + Type: "AWS::EC2::SecurityGroupIngress" + Properties: + Description: Allow SSH from Bastion server to Regular Nodes + GroupId: !GetAtt ArtifactorySecondaryNodesStack.Outputs.EKSNodeSecurityGroup + SourceSecurityGroupId: !GetAtt EKSStack.Outputs.BastionSecurityGroup + IpProtocol: tcp + ToPort: 22 + FromPort: 22 + # Allow the secondary node pools to bidirectionally communicate with "initial" (master) nodes + RegularToMasterIngress: + Type: AWS::EC2::SecurityGroupIngress + Properties: + Description: Allows regular nodes to communicate with master nodes + GroupId: !GetAtt EKSStack.Outputs.NodeGroupSecurityGroup + SourceSecurityGroupId: !GetAtt ArtifactorySecondaryNodesStack.Outputs.EKSNodeSecurityGroup + IpProtocol: '-1' + FromPort: 0 + ToPort: 65535 + MasterToRegularIngress: + Type: AWS::EC2::SecurityGroupIngress + Properties: + Description: Allows master nodes to communicate with regular agent nodes + GroupId: !GetAtt ArtifactorySecondaryNodesStack.Outputs.EKSNodeSecurityGroup + SourceSecurityGroupId: !GetAtt EKSStack.Outputs.NodeGroupSecurityGroup + IpProtocol: '-1' + FromPort: 0 + ToPort: 65535 + ArtifactoryCoreInfraStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub "https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-artifactory-core-infrastructure.template.yaml" + Parameters: + VPCID: !Ref VPCID + VPCCIDR: !Ref VPCCIDR + PrivateSubnet1CIDR: !Ref PrivateSubnet1CIDR + PrivateSubnet2CIDR: !Ref PrivateSubnet2CIDR + PrivateSubnet3CIDR: !Ref PrivateSubnet3CIDR + SubnetIds: !Join [ ",", [ !Ref PrivateSubnet1ID, !Ref PrivateSubnet2ID, !Ref PrivateSubnet3ID ]] + DBAllocatedStorage: !Ref DBAllocatedStorage + MultiAZDatabase: !Ref MultiAZDatabase + DatabaseEngine: !Ref DatabaseEngine + DatabaseVersion: !Ref DatabaseVersion + DatabaseUser: !Ref DatabaseUser + DatabasePassword: !Ref DatabasePassword + DatabaseInstance: !Ref DatabaseInstance + DatabaseName: !Ref DatabaseName + ArtifactoryCoreStack: + DependsOn: ArtifactorySecondaryNodesStack + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub "https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-eks-core-workload.template.yaml" + Parameters: + KubeManifestLambdaArn: !GetAtt EKSStack.Outputs.KubeManifestLambdaArn + HelmLambdaArn: !GetAtt EKSStack.Outputs.HelmLambdaArn + KubeConfigPath: !GetAtt EKSStack.Outputs.KubeConfigPath + KubeConfigKmsContext: !Ref KubeConfigKmsContext + KubeGetLambdaArn: !GetAtt EKSStack.Outputs.KubeGetLambdaArn + NumberOfSecondary: !Ref NumberOfSecondary + AccessCIDR: !Ref AccessCIDR + ArtifactoryLicense1: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense1}}' + ArtifactoryLicense2: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense2}}' + ArtifactoryLicense3: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense3}}' + ArtifactoryLicense4: !Sub '{{resolve:secretsmanager:${SMLicensesName}:SecretString:ArtifactoryLicense4}}' + CertificateKey: !Ref CertificateKey + Certificate: !Ref Certificate + CertificateDomain: !Ref CertificateDomain + PrivateRepoUsername: !Ref PrivateRepoUsername + PrivateRepoApiKey: !Ref PrivateRepoApiKey + ArtifactoryIAMAcessKey: !GetAtt ArtifactoryCoreInfraStack.Outputs.IAMAcessKey + SecretAccessKey: !GetAtt ArtifactoryCoreInfraStack.Outputs.SecretAccessKey + ArtifactoryS3Bucket: !GetAtt ArtifactoryCoreInfraStack.Outputs.S3Bucket + ArtifactoryDBEndpointAddress: !GetAtt ArtifactoryCoreInfraStack.Outputs.ArtifactoryDBEndpointAddress + DatabaseName: !Ref DatabaseName + DatabaseUser: !Ref DatabaseUser + DatabasePassword: !Ref DatabasePassword + MasterKey: !Ref MasterKey + ArtifactoryVersion: !Ref ArtifactoryVersion + ArtifactoryDeploymentSize: !Ref ArtifactoryDeploymentSize +Outputs: + ArtifactoryUrl: + Value: !GetAtt ArtifactoryCoreStack.Outputs.ArtifactoryUrl + Description: Public Artifactory URL + BastionIP: + Value: !GetAtt EKSStack.Outputs.BastionIP + Description: Bastion host IP, for admin access via SSH + KubeConfigPath: + Value: !GetAtt EKSStack.Outputs.KubeConfigPath + Description: (Advanced) Amazon S3 bucket containing encrypted Kubernetes config which can be used to access the Kubernetes API. diff --git a/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-master.template.yaml b/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-master.template.yaml new file mode 100755 index 0000000..03034e0 --- /dev/null +++ b/CloudFormation-JCR-EKS/templates/jfrog-jcr6-eks-master.template.yaml @@ -0,0 +1,598 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: 'JFrog Artifactory Quick Start Deployment' +Metadata: + AWS::CloudFormation::Interface: + ParameterGroups: + - Label: + default: Security configuration + Parameters: + - KeyPairName + - AccessCIDR + - RemoteAccessCIDR + - AdditionalEKSAdminArns + - KubeConfigKmsContext + - Label: + default: Network configuration + Parameters: + - AvailabilityZones + - VPCCIDR + - PrivateSubnet1CIDR + - PrivateSubnet2CIDR + - PrivateSubnet3CIDR + - PublicSubnet1CIDR + - PublicSubnet2CIDR + - PublicSubnet3CIDR + - Label: + default: Bastion configuration + Parameters: + - ProvisionBastionHost + - BastionInstanceType + - BastionOS + - BastionRootVolumeSize + - BastionEnableTCPForwarding + - BastionEnableX11Forwarding + - Label: + default: JFrog Artifactory configuration + Parameters: + - ArtifactoryVersion + - ArtifactoryDeploymentSize + - NumberOfSecondary + - SMLicensesName + - Certificate + - CertificateKey + - CertificateDomain + - MasterKey + - PrivateRepoUsername + - PrivateRepoApiKey + - Label: + default: Amazon RDS configuration + Parameters: + - DatabaseName + - DatabaseEngine + - DatabaseVersion + - DatabaseUser + - DatabasePassword + - DatabaseInstance + - DBAllocatedStorage + - MultiAZDatabase + - Label: + default: EC2/EKS configuration + Parameters: + - NodeInstanceType + - NodeVolumeSize + - NumofSecondaryNodes + - KubernetesVersion + - Label: + default: AWS Quick Start configuration + Parameters: + - QSS3BucketName + - QSS3KeyPrefix + - LambdaZipsBucketName + ParameterLabels: + KeyPairName: + default: SSH key name + AccessCIDR: + default: Permitted IP range + RemoteAccessCIDR: + default: Remote access CIDR + AdditionalEKSAdminArns: + default: Additional EKS admin ARNs + KubeConfigKmsContext: + default: Kubernetes config KMS context + AvailabilityZones: + default: Availability Zones + VPCCIDR: + default: VPC CIDR + PrivateSubnet1CIDR: + default: Private subnet 1 CIDR + PrivateSubnet2CIDR: + default: Private subnet 2 CIDR + PrivateSubnet3CIDR: + default: Private subnet 3 CIDR + PublicSubnet1CIDR: + default: Public subnet 1 CIDR + PublicSubnet2CIDR: + default: Public subnet 2 CIDR + PublicSubnet3CIDR: + default: Public subnet 3 CIDR + ProvisionBastionHost: + default: Bastion instance + BastionInstanceType: + default: Bastion instance type + BastionRootVolumeSize: + default: Bastion root volume size + BastionEnableTCPForwarding: + default: Bastion enable TCP forwarding + BastionEnableX11Forwarding: + default: Bastion enable X11 forwarding + BastionOS: + default: Bastion operating system + NumberOfSecondary: + default: Number of secondary pods + ArtifactoryVersion: + default: Artifactory version + ArtifactoryDeploymentSize: + default: Artifactory deployment size + SMLicensesName: + default: Artifactory licenses secret name + Certificate: + default: Certificate + CertificateKey: + default: Certificate key + CertificateDomain: + default: Certificate domain + PrivateRepoUsername: + default: Username to include for private RPM repository + PrivateRepoApiKey: + default: Api Key for private RPM repository + MasterKey: + default: Master server key + DatabaseName: + default: Database name + DatabaseEngine: + default: Database engine + DatabaseVersion: + default: Database version + DatabaseUser: + default: Database user + DatabasePassword: + default: Database password + DatabaseInstance: + default: Database instance type + DBAllocatedStorage: + default: Database allocated storage + MultiAZDatabase: + default: High available database + NodeInstanceType: + default: Node instance type + NodeVolumeSize: + default: Node EBS volume size + NumofSecondaryNodes: + default: Number of secondary nodes + KubernetesVersion: + default: Kubernetes version + QSS3BucketName: + default: Quick Start S3 bucket name + QSS3KeyPrefix: + default: Quick Start S3 key prefix + LambdaZipsBucketName: + default: Lambda zips bucket name +Parameters: + KeyPairName: + Description: The name of an existing public/private key pair, which allows you + to securely connect to your instance after it launches. + Type: AWS::EC2::KeyPair::KeyName + AccessCIDR: + Description: The CIDR IP range that is permitted to access Artifactory. + We recommend that you set this value to a trusted IP range. + For example, you might want to grant only your corporate network access to the software. + 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ + Type: String + RemoteAccessCIDR: + Description: + The remote CIDR range for allowing SSH into the Bastion instance. + We recommend that you set this value to a trusted IP range. + For example, you might want to grant specific ranges inside your corporate network SSH access. + 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])(\/([0-9]|[1-2][0-9]|3[0-2]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/x + Type: String + AdditionalEKSAdminArns: + Description: '[OPTIONAL] The Amazon Resource Names (ARNs): a comma-separated list of IAM users and roles to be granted admin access to the EKS cluster.' + Default: "" + Type: CommaDelimitedList + KubeConfigKmsContext: + Description: String value used by KMS to encrypt/decrypt Kubernetes configuration file. + Default: "JFrogArtifactory" + Type: String + AvailabilityZones: + Description: + The list of Availability Zones to use for the subnets in the VPC. Three + Availability Zones are used for this deployment, and the logical order of your + selections is preserved. + Type: List + VPCCIDR: + Description: The CIDR block for the VPC. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.0.0/16 + Type: String + PrivateSubnet1CIDR: + Description: The CIDR block for private subnet 1 located in Availability Zone 1. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.0.0/19 + Type: String + PrivateSubnet2CIDR: + Description: The CIDR block for private subnet 2 located in Availability Zone 2. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.32.0/19 + Type: String + PrivateSubnet3CIDR: + Description: The CIDR block for private subnet 3 located in Availability Zone 3. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.64.0/19 + Type: String + PublicSubnet1CIDR: + Description: + The CIDR block for the public (DMZ) subnet 1 located in Availability Zone 1. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.128.0/20 + Type: String + PublicSubnet2CIDR: + Description: + The CIDR block for the public (DMZ) subnet 2 located in Availability Zone 2. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.144.0/20 + Type: String + PublicSubnet3CIDR: + Description: The CIDR block for the public (DMZ) subnet 3 located in Availability Zone 3. + 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]))$ + ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 + Default: 10.0.160.0/20 + Type: String + NodeInstanceType: + Description: The Amazon EC2 instance type for the nodes hosting the Kubernetes pods. + AllowedValues: + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + - m4.10xlarge + ConstraintDescription: Must be a valid EC2 instance type. + Default: m4.xlarge + Type: String + NodeVolumeSize: + Description: The size of EBS volumes for master node instances, in GB. + Default: 200 + Type: String + NumofSecondaryNodes: + Description: The initial number of secondary node instances to create. + If you do not have large enough instances to boot the number of secondary pods, the deployment will fail. + AllowedValues: + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + Default: 2 + Type: Number + KubernetesVersion: + Description: The Kubernetes control plane version. + AllowedValues: [ "1.13", "1.12", "1.11" ] + Default: "1.13" + Type: String + ProvisionBastionHost: + Description: Choose Disabled to skip creating a bastion instance. Due to the Artifactory nodes being + created in private subnets, the default setting of Enabled this is highly recommended. + AllowedValues: + - "Enabled" + - "Disabled" + Default: "Enabled" + Type: String + BastionInstanceType: + Description: The size of the bastion instances. + AllowedValues: + - t2.nano + - t2.micro + - t2.small + - t2.medium + - t2.large + - m3.large + - m3.xlarge + - m3.2xlarge + - m4.large + - m4.xlarge + - m4.2xlarge + - m4.4xlarge + Default: "t2.micro" + Type: String + BastionRootVolumeSize: + Description: The size of the root volume on the bastion instances. + Default: 10 + Type: Number + BastionEnableTCPForwarding: + Description: Choose whether to enable TCPForwarding via the bootstrapping of the bastion instance + or not. + AllowedValues: + - "true" + - "false" + Default: "true" + Type: String + BastionEnableX11Forwarding: + Description: Choose true to enable X11 via the bootstrapping of the bastion host. + Setting this value to true will enable X Windows over SSH. + X11 forwarding can be very useful but it is also a security risk, so we recommend + that you keep the default (false) setting unless required. + AllowedValues: + - "true" + - "false" + Default: "false" + Type: String + BastionOS: + Description: The Linux distribution for the Amazon Machine Image (AMI) to be used for the bastion instances. + AllowedValues: + - "Amazon-Linux-HVM" + - "CentOS-7-HVM" + - "Ubuntu-Server-14.04-LTS-HVM" + - "Ubuntu-Server-16.04-LTS-HVM" + - "SUSE-SLES-15-HVM" + Default: "Amazon-Linux-HVM" + Type: String + NumberOfSecondary: + Description: Number of secondary Artifactory pods to complete your HA deployment. + Minimum number of 2 to fit the Artifactory best practices. Do not select more than + you license for. + AllowedValues: + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + Default: 2 + Type: Number + ArtifactoryVersion: + Description: The version of Artifactory that you want to deploy into the Quick Start. + Please see the release notes to select the version you want to deploy. + https://www.jfrog.com/confluence/display/RTF/Release+Notes + #AllowedPattern: ^(([0-9]|[1-9][0-9])\.){2}([1-9][0-9]|[0-9])$ + #ConstraintDescription: A version that matches X.X.X per Artifactory releases. + Default: 6.15.0 + Type: String + ArtifactoryDeploymentSize: + Description: Configuration settings implemented by the Helm chart. There are currently three supported sizes. + 'Large:' Memory request of 6 GiB, memory limit of 10GiB; CPU request of 4, CPU limit of 8; Java heap size minimum of 6 GB, maximum of 8 GB. + 'Medium:' Memory request of 4 GiB, memory limit of 8 GiB; CPU request of 2, CPU limit of 6; Java heap size minimum of 4 GB, maximum of 6 GB. + 'Small:' Memory request of 4 GiB, memory limit of 6 GiB; CPU request of 2, CPU limit of 4; Java heap size of 4 GB. + AllowedValues: + - Small + - Medium + - Large + Default: Medium + Type: String + SMLicensesName: + Description: The secret name created in AWS Secrets Manager which contains the Artifactory licenses. + Type: String + Certificate: + Description: The certificate file to be used to terminate SSL. + AllowedPattern: ^(-----BEGIN CERTIFICATE-----)\n(.*?\n)+(-----END CERTIFICATE-----)$ + ConstraintDescription: A Certificate that begins with "-----BEGIN CERTIFICATE----- " and ends with "-----END CERTIFICATE----- " + Type: String + CertificateKey: + Description: The private key for the certificate. + AllowedPattern: ^(-----BEGIN [A-Za-z ]+ KEY-----)\n(.*?\n)+(-----END [A-Za-z ]+ KEY-----)$ + ConstraintDescription: A Private key that begins with "-----BEGIN PRIVATE KEY-----" and ends with "-----END PRIVATE KEY-----" + NoEcho: 'true' + Type: String + CertificateDomain: + Description: The domain matching that of the certificate. Ensure that it matches your certificate. + AllowedPattern: ^[A-Za-z0-9]+[.A-Za-z0-9]+[A-Za-z0-9]$ + ConstraintDescription: The domain must not start or end with a '.' + Type: String + PrivateRepoUsername: + Description: Username to include for private RPM repository + NoEcho: 'true' + Type: String + PrivateRepoApiKey: + Description: Api Key for private RPM repository + NoEcho: 'true' + Type: String + MasterKey: + Description: The master key for the Artifactory cluster. Generate a master key by using the command '$openssl rand -hex 16'. + AllowedPattern: ^[a-zA-Z0-9]+$ + MinLength: '1' + MaxLength: '64' + ConstraintDescription: Only capital or lowercase letters and numbers, with a Max of 64 characters. + NoEcho: 'true' + Type: String + DatabaseName: + Description: The name for your DB instance. The name must be unique across all DB instances + owned by your AWS account in the current AWS Region. The DB instance identifier is case-insensitive, + but is stored as all lowercase (as in "mydbinstance"). + AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ + MinLength: '1' + MaxLength: '60' + ConstraintDescription: 1 to 60 alphanumeric characters First character must be a letter. + Default: artdb + Type: String + DatabaseEngine: + Description: The database engine that you want to run, currently locked to MySQL. + AllowedValues: + - MySQL + Default: MySQL + Type: String + DatabaseVersion: + Description: The major version of the MySQL database engine you want to run. This is currently locked to MySQL versions + supported by Artifactory and RDS. + AllowedValues: + - 5.5 + - 5.6 + - 5.7 + Default: 5.7 + Type: String + DatabaseUser: + Description: The login ID for the master user of your DB instance. + MinLength: '1' + MaxLength: '16' + AllowedPattern: ^[a-zA-Z]([a-zA-Z0-9])+$ + ConstraintDescription: 1 to 16 alphanumeric characters. First character must be a letter + Default: artifactory + Type: String + DatabasePassword: + Description: The password for the Artifactory database user. + AllowedPattern: ^[^ \\']+$ + MinLength: '8' + MaxLength: '12' + ConstraintDescription: Must be at least 8 and no more than + 12 characters containing letters and (minimum 1 capital letter), numbers and + symbols. + NoEcho: 'true' + Type: String + DatabaseInstance: + Description: The size of the database to be deployed as part of the Quick Start. + AllowedValues: + - db.t3.medium + - db.m3.medium + - db.m3.large + - db.m3.xlarge + - db.m3.2xlarge + - db.m4.large + - db.m4.xlarge + - db.m4.2xlarge + - db.m4.10xlarge + - db.m4.16xlarge + - db.m5.large + - db.m5.xlarge + - db.m5.2xlarge + - db.m5.4xlarge + - db.m5.12xlarge + - db.m5.24xlarge + ConstraintDescription: Must be a valid database Instance Type. + Default: db.t3.medium + Type: String + DBAllocatedStorage: + Description: The size in GB of the available storage for the database instance. + MinValue: 5 + MaxValue: 1024 + Default: 10 + Type: Number + MultiAZDatabase: + Description: Choose false to create an Amazon RDS instance in a single Availability Zone. + ConstraintDescription: True or False + AllowedValues: + - "true" + - "false" + Default: "true" + Type: String + QSS3BucketName: + AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ + ConstraintDescription: + Quick Start bucket name can include numbers, lowercase + letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen + (-). + Default: aws-quickstart + Description: + S3 bucket name for the Quick Start assets. This string can include + numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start + or end with a hyphen (-). + Type: String + QSS3KeyPrefix: + AllowedPattern: ^[0-9a-zA-Z-/]*$ + ConstraintDescription: + Quick Start key prefix can include numbers, lowercase letters, + uppercase letters, hyphens (-), and forward slash (/). + Default: quickstart-jfrog-artifactory/ + Description: + S3 key prefix for the Quick Start assets. Quick Start key prefix + can include numbers, lowercase letters, uppercase letters, hyphens (-), and + forward slash (/). + Type: String + LambdaZipsBucketName: + Description: '[OPTIONAL] The name of the S3 bucket where the Lambda .zip + files should be placed. If you leave this parameter blank, an S3 bucket will be created.' + Type: String + Default: '' +Rules: + EKSSupport: + Assertions: + - AssertDescription: Your AWS Region does *NOT* yet support Amazon EKS + Assert: !Contains + - - us-west-2 + - us-east-1 + - us-east-2 + - eu-west-1 + - eu-west-2 + - eu-west-3 + - eu-north-1 + - eu-central-1 + - ap-southeast-1 + - ap-southeast-2 + - ap-northeast-1 + - ap-northeast-2 + - ap-south-1 + - !Ref 'AWS::Region' + +Resources: + VPCStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template + Parameters: + KeyPairName: !Ref KeyPairName + AvailabilityZones: !Join [",", !Ref AvailabilityZones] + NumberOfAZs: '3' + VPCCIDR: !Ref VPCCIDR + PrivateSubnet1ACIDR: !Ref 'PrivateSubnet1CIDR' + PrivateSubnet2ACIDR: !Ref 'PrivateSubnet2CIDR' + PrivateSubnet3ACIDR: !Ref 'PrivateSubnet3CIDR' + PrivateSubnetATag2: "kubernetes.io/role/internal-elb=" + PublicSubnet1CIDR: !Ref 'PublicSubnet1CIDR' + PublicSubnet2CIDR: !Ref 'PublicSubnet2CIDR' + PublicSubnet3CIDR: !Ref 'PublicSubnet3CIDR' + PublicSubnetTag2: "kubernetes.io/role/elb=" + ArtifactoryEKSExistingVPCStack: + Type: AWS::CloudFormation::Stack + Properties: + TemplateURL: !Sub 'https://${QSS3BucketName}.s3.amazonaws.com/${QSS3KeyPrefix}templates/jfrog-jcr6-eks-existing-vpc.template.yaml' + Parameters: + KeyPairName: !Ref KeyPairName + AccessCIDR: !Ref AccessCIDR + RemoteAccessCIDR: !Ref RemoteAccessCIDR + AdditionalEKSAdminArns: !Join [ ",", !Ref AdditionalEKSAdminArns ] + KubeConfigKmsContext: !Ref KubeConfigKmsContext + VPCID: !GetAtt VPCStack.Outputs.VPCID + VPCCIDR: !Ref VPCCIDR + PrivateSubnet1ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet1AID' + PrivateSubnet2ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet2AID' + PrivateSubnet3ID: !GetAtt 'VPCStack.Outputs.PrivateSubnet3AID' + PublicSubnet1ID: !GetAtt 'VPCStack.Outputs.PublicSubnet1ID' + PublicSubnet2ID: !GetAtt 'VPCStack.Outputs.PublicSubnet2ID' + PublicSubnet3ID: !GetAtt 'VPCStack.Outputs.PublicSubnet3ID' + PrivateSubnet1CIDR: !Ref PrivateSubnet1CIDR + PrivateSubnet2CIDR: !Ref PrivateSubnet2CIDR + ProvisionBastionHost: !Ref ProvisionBastionHost + BastionInstanceType: !Ref BastionInstanceType + BastionOS: !Ref BastionOS + BastionRootVolumeSize: !Ref BastionRootVolumeSize + BastionEnableTCPForwarding: !Ref BastionEnableTCPForwarding + BastionEnableX11Forwarding: !Ref BastionEnableX11Forwarding + ArtifactoryVersion: !Ref ArtifactoryVersion + ArtifactoryDeploymentSize: !Ref ArtifactoryDeploymentSize + NumberOfSecondary: !Ref NumberOfSecondary + SMLicensesName: !Ref SMLicensesName + Certificate: !Ref Certificate + CertificateKey: !Ref CertificateKey + CertificateDomain: !Ref CertificateDomain + PrivateRepoUsername: !Ref PrivateRepoUsername + PrivateRepoApiKey: !Ref PrivateRepoApiKey + MasterKey: !Ref MasterKey + DatabaseName: !Ref DatabaseName + DatabaseEngine: !Ref DatabaseEngine + DatabaseVersion: !Ref DatabaseVersion + DatabaseUser: !Ref DatabaseUser + DatabasePassword: !Ref DatabasePassword + DatabaseInstance: !Ref DatabaseInstance + DBAllocatedStorage: !Ref DBAllocatedStorage + MultiAZDatabase: !Ref MultiAZDatabase + KubernetesVersion: !Ref KubernetesVersion + NodeInstanceType: !Ref NodeInstanceType + NodeVolumeSize: !Ref NodeVolumeSize + NumofSecondaryNodes: !Ref NumofSecondaryNodes + QSS3BucketName: !Ref QSS3BucketName + QSS3KeyPrefix: !Ref QSS3KeyPrefix + LambdaZipsBucketName: !Ref LambdaZipsBucketName + +Outputs: + ArtifactoryUrl: + Value: !GetAtt ArtifactoryEKSExistingVPCStack.Outputs.ArtifactoryUrl + Description: Public Artifactory URL + BastionIP: + Value: !GetAtt ArtifactoryEKSExistingVPCStack.Outputs.BastionIP + Description: Bastion host IP, for admin access via SSH + KubeConfigPath: + Value: !GetAtt ArtifactoryEKSExistingVPCStack.Outputs.KubeConfigPath + Description: (Advanced) Amazon S3 bucket containing encrypted Kubernetes config which can be used to access the Kubernetes API.