added Cloud Formation templates for ECS and EKS

This commit is contained in:
Vinay Aggarwal
2019-11-18 16:54:25 -08:00
parent 8e7a87dfe1
commit 5d2fb7a659
40 changed files with 4690 additions and 0 deletions

12
CloudFormation-JCR-ECS/.gitmodules vendored Normal file
View File

@@ -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

View File

@@ -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.

View File

@@ -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") '

View File

View File

@@ -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"
}
]

View File

@@ -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

View File

@@ -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
------------------

View File

@@ -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

View File

@@ -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<String> 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"
}
}

View File

@@ -0,0 +1,7 @@
{
"productId": "JFrogInstaller_Cloudformation/1.0.0",
"features": [
{
"featureId": "MySql/5.5"
}]
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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'

View File

@@ -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'

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 %}

View File

@@ -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 }} ~(?<repo>.+)\.{{ 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;
}
}

View File

@@ -0,0 +1,38 @@
<config version="2">
<chain> <!--template="cluster-s3"-->
<provider id="cache-fs-eventual-s3" type="cache-fs">
<provider id="sharding-cluster-eventual-s3" type="sharding-cluster">
<sub-provider id="eventual-cluster-s3" type="eventual-cluster">
<provider id="retry-s3" type="retry">
<provider id="s3" type="s3"/>
</provider>
</sub-provider>
<dynamic-provider id="remote-s3" type="remote"/>
</provider>
</provider>
</chain>
<provider id="sharding-cluster-eventual-s3" type="sharding-cluster">
<readBehavior>crossNetworkStrategy</readBehavior>
<writeBehavior>crossNetworkStrategy</writeBehavior>
<redundancy>2</redundancy>
<lenientLimit>1</lenientLimit>
<property name="zones" value="local,remote"/>
</provider>
<provider id="remote-s3" type="remote">
<zone>remote</zone>
</provider>
<provider id="eventual-cluster-s3" type="eventual-cluster">
<zone>local</zone>
</provider>
<provider id="s3" type="s3">
<endpoint>{{ s3_endpoint }}</endpoint>
<identity>{{ s3_access_key }}</identity>
<credential>{{ s3_access_secret_key }}</credential>
<bucketName>{{ s3_bucket }}</bucketName>
<property name="s3service.server-side-encryption" value="AES256"/>
</provider>
</config>

View File

@@ -0,0 +1 @@
{{ certificate_key | b64decode }}

View File

@@ -0,0 +1,2 @@
{{ certificate | b64decode }}

View File

@@ -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 }}

View File

@@ -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 }}

View File

@@ -0,0 +1 @@
{{ master_key }}

View File

@@ -0,0 +1,5 @@
- hosts: localhost
gather_facts: true
become: true
roles:
- name: artifactory

View File

@@ -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

View File

@@ -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
- ""

View File

@@ -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<AWS::EC2::AvailabilityZone::Name>
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

View File

@@ -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