├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Figures ├── appstreamfleet.png ├── appstreamimage.png ├── appstreamimageregistry.png ├── appstreamstack.png ├── deploymentoutput.png ├── ecs-task-omero-server.png ├── ecsaccountsetting.png ├── filegateway.png ├── fileshare.png ├── fileshareowner.png ├── launchstack.png ├── omero-cloudwatch-dashboard.png ├── omero-on-aws-ha ├── omero-on-aws-ha.jpg ├── omero-on-aws-rw-fargate.jpg ├── omero-on-aws-rw.jpg ├── omero-server-blitz-log.png ├── omero-server-ip.png ├── omero-server-logs-cw.png ├── omeroinsight.png ├── omerowebimageurl.png ├── securitygroup.png └── storagegateway.jpg ├── LICENSE ├── OMERO-cloudformation-templates ├── OMERO2LBstackTLS_RW.yml ├── OMERO2LBstackTLS_RW_StorageGateway.yml ├── OMERONetworkInfra.yaml ├── OMERO_DataSync.yaml ├── OMEROonECS_ALBNLBwithTLS_RW.yaml ├── OMEROonECS_ALBNLBwithTLS_RW_StorageGateway.yaml ├── OMEROonECS_ALBwithTLS_RW.yaml ├── OMEROonECS_ALBwithTLS_RW_RO.yml ├── OMEROonECS_Monitoring.yaml ├── OMEROonECS_RW.yaml ├── OMEROonECS_RW_S3FG.yml ├── OMEROonECS_RW_TLS_S3FG.yml ├── OMEROstackTLS_RW.yml ├── OMEROstackTLS_RW_RO.yml ├── OMEROstack_RW.yml ├── OMEROstorage.yaml ├── ec2s3filegateway.yaml └── omero_ec2_uploader_template.yaml ├── README.md └── custom-docker-container ├── README.md ├── omero-server ├── Dockerfile └── playbook.yml └── omero-web ├── 01-default-webapps.omero ├── Dockerfile └── build_and_push.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | ### Cloud9 ### 4 | # Cloud9 IDE - http://c9.io 5 | .c9revisions 6 | .c9 7 | 8 | ### Java ### 9 | # Compiled class file 10 | *.class 11 | 12 | # Log file 13 | *.log 14 | 15 | # compiled output 16 | /dist 17 | /tmp 18 | /out-tsc 19 | 20 | # Package Files # 21 | *.jar 22 | *.war 23 | *.nar 24 | *.ear 25 | *.zip 26 | *.tar.gz 27 | *.rar 28 | 29 | ### Maven ### 30 | target/ 31 | pom.xml.tag 32 | pom.xml.releaseBackup 33 | pom.xml.versionsBackup 34 | pom.xml.next 35 | release.properties 36 | dependency-reduced-pom.xml 37 | buildNumber.properties 38 | .mvn/timing.properties 39 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar 40 | .mvn/wrapper/maven-wrapper.jar 41 | 42 | # Eclipse m2e generated files 43 | # Eclipse Core 44 | .project 45 | # JDT-specific (Eclipse Java Development Tools) 46 | .classpath 47 | 48 | ### Node ### 49 | # Logs 50 | logs 51 | npm-debug.log* 52 | yarn-debug.log* 53 | yarn-error.log* 54 | lerna-debug.log* 55 | .pnpm-debug.log* 56 | 57 | # Only exists if Bazel was run 58 | /bazel-out 59 | 60 | # Dependency directories 61 | node_modules/ 62 | jspm_packages/ 63 | 64 | # TypeScript cache 65 | *.tsbuildinfo 66 | 67 | # Optional npm cache directory 68 | .npm 69 | 70 | # profiling files 71 | chrome-profiler-events*.json 72 | 73 | # IDEs and editors 74 | /.idea 75 | .project 76 | .classpath 77 | .c9/ 78 | *.launch 79 | .settings/ 80 | *.sublime-workspace 81 | 82 | ### VisualStudioCode ### 83 | .vscode/* 84 | !.vscode/settings.json 85 | !.vscode/tasks.json 86 | !.vscode/launch.json 87 | !.vscode/extensions.json 88 | !.vscode/*.code-snippets 89 | .history/ 90 | *.vsix 91 | 92 | # System Files 93 | ._* 94 | .DS_Store 95 | Thumbs.db 96 | 97 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /Figures/appstreamfleet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/appstreamfleet.png -------------------------------------------------------------------------------- /Figures/appstreamimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/appstreamimage.png -------------------------------------------------------------------------------- /Figures/appstreamimageregistry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/appstreamimageregistry.png -------------------------------------------------------------------------------- /Figures/appstreamstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/appstreamstack.png -------------------------------------------------------------------------------- /Figures/deploymentoutput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/deploymentoutput.png -------------------------------------------------------------------------------- /Figures/ecs-task-omero-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/ecs-task-omero-server.png -------------------------------------------------------------------------------- /Figures/ecsaccountsetting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/ecsaccountsetting.png -------------------------------------------------------------------------------- /Figures/filegateway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/filegateway.png -------------------------------------------------------------------------------- /Figures/fileshare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/fileshare.png -------------------------------------------------------------------------------- /Figures/fileshareowner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/fileshareowner.png -------------------------------------------------------------------------------- /Figures/launchstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/launchstack.png -------------------------------------------------------------------------------- /Figures/omero-cloudwatch-dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/omero-cloudwatch-dashboard.png -------------------------------------------------------------------------------- /Figures/omero-on-aws-ha: -------------------------------------------------------------------------------- 1 | 7Z1be6OqGsc/TS/tgwIeLnucds+hnXbNmjX7Jg8qJu4xMduYpu2nXxA19YA2mSYNpsz0mamoCAj8/ry+wBE8Gz9+Ssh09DX2aXRkAP/xCJ4fGYYOgcH+4yFPeYiFYRYyTEI/D3sJuA+faR4I8tB56NNZ5cI0jqM0nFYDvXgyoV5aCSNJEi+qlwVxVH3qlAxpI+DeI1Ez9Gfop6Ms1MbgJfyKhsNR8WQd5GfGpLg4D5iNiB8vSkHw4gieJXGcZr+NH89oxEuvKJf8vgl9TPmZa/9vEs3zZEG8iuGOzuJ54tFzOvOScJrGCbspyQOzqwdH8KRIBU1CEoXPJA3jifZAkxn7P7vqIb+E5EWWCCLOn3lPx2SSht45SclZPElJOKHJOrFnd6dJOBl+CVOakCh7dymdpJVcT5N4SpM0rzajNOXv++TIuGQ/7PI4iodPxzPqzZMwfTomY/IcT459+sBOB/F84i9TwA78kAwTMtYewtl8lTIWTgwDYwebmgf9QEOe4Wkush12CKzAtInrOdYyJZdZmq/vrhvFulGqWC0OhxMtnMymrJ7ysrz04vE0nrCcz9iBjYgNXBxo2ESGhohuaQ62sUbdwHdNHCCXetstmtnTLKVjbcwbLXsfLAQgDB3sWBoybKihwMSaDRygEWpageND6iCnXCjsF3FNKM4K6mZxKq/u4qq/anVJtV5sUuH1nlR4XVX4D1fhY/d/HFYGiIjLiLnMV15dWcXwwuivp2le5kPK4g89bVV22XVFS/mEwXjw+fP19+foRic/h1dXqbbQdGdV91Zta5Y+FVBLeKlQHoN+BE9J4uXcZdCFpz6ZjZbn+MEsTeLf9IwVcbK8FYLlH3YmCKOoCJ+whLEgVu/8kKWwFpzFUdCTJet0lI6j/OFZbljDSelja9vPgxI/+DHlD6G+qOmEdHaS0JPpNAo94hZ5BaWS+ETjMU2TJ3ZP/rCi2PO6pRWyY/HCeoztLGxU4rwFan3HcBX1S21Zs6PqeoVy9F877wtQgHXH0QMtgJ7J+gLE+gIXAA3oEJuAuI4RoLa+YJWGxWJxvIDHccJbNovO4Q2cvw32XlnV0WZPLN+P2oQ9EKa8fW2zt6t0NEMuhjVW7+deOk8oT4eLKCWerQFEsYYo6+ds02FdsI/NwHWQ5Vqu3Bk8xO68k8s/Jr8n8WJyywcI70JogD0PQ93TfAPpGnI8yFLv8zoCLcvyMDLMYO3Ud3cqsomNbXGVJz9D65Yx68zJ/PP1L+c/Orn/soiMZ3wX5LB4I2V1EWUvsXOOzY0oyyO8JSmrDLz/ZsgCSHL2QgQq8IVN9hoFZsvsNeH22NvxXuVAb2cj70y9bG1cEUhAIKWseq+s+i0iekpesy/j24AV6H2eMhmYa1aZazeZq5sC5urGrplr9pq5pmKuYq5irmLu4TJ3GybljzvYNSUd60pkZd4cu5JasxR1FXUVdRV169R9CJOUZWEwTcIHktKBF8Vzfw3yGp3krYxnS8CbjcjywePHZVU6JosZPBYnoYreJZJtDM12/r4dpq2grBmFNcNukBIbTVBCc7ecLN5pLzlpKE4qTipOKk72g5N/MjqFWxid9sThqRWddhWdK5SWjbuWYJCJtujM1P5y+gpPqOCp4KngqeApHTzNiJ0+Za/DHPJfbrMxHbvqfu5OaFpcwOJaXcNOFn7xdeqychyHM95pztbgLdremLT84MZI9Nw5sZC+l5GoY1ZxqsNj3AAqFPAU4t3iFPUZp63do8KpwqnC6bvitEkM0DobSZwag4+NWGrYbZfLpHgj1p+wdGSgUlzf66D4ZZLoxx0Uw2L6jnSjYtxnjGOFcYVxhXEpMK7o+fZRcRt2NxsVd7slH8SoGFqyDot77UGsHIgVTxVP5eCpYFhsqGGxbGA/mSdxwsoU3MazdJjQ++9f2MEdXXrliikvJHzizwa+O2CNMSUTjw4SSnz2Tx7Nq8i3O5Efz1PWybChc7E6VWNszSHNnhR94VllWQnTDChunKbxuHTBScT6DHYijad8uJ4feayy8PJ+VU90ZrMhMIwLC57a+3EA06sCAwsG7MgpNEfFWXrHPmB2nwWGrQSGEhhKYEghMF5Bl1Iah2KA18uoO3AL/JumR9m4wnx5piX3ZRXBztQr6CvoK+grK71EiK1b6ecuo0XNESG/JnkZwK89qC+Guesw2uhk9EZG+9VjZZpRtVqSOq9pCAkM9khAV1yso70ruBZSq59wbbUJKrgquCq4vq/JXsQPNY6WC/I3Xy/ubo4X1N0A5NQzBryhzflk5Zde/XWqd/u+yWOXF2dQrB/QLvXDm8bvOqxqDMNyGhJDNICHKy2yM5HRazc7XfnZKZGhRIYcIqPELyUt9iotmnKvzWq/iSHAksEQsP0FQztc+aqu8fIYBqxeM9tSzFbMVsyWgtmtpFD03hu9azpqe2P+vvjibWnML9na4kiv2wAsgZ7YkxWg1757unLeU4pCKQo5FIWyAsiiI1rkA5mn8WDGKL1sv6+qBqPbR08e1VDJV98+EBjmappgsQS6I5IHopn4prNbcWD02slPbSCsxIESB5KIA4XnV/GcMKKuNZzPYugBmPMc9Q/JqIZkDTf97gv4Vna/NnYM5KLu9BPIrRZGBWQFZAVkBeQ9AfnblzYvO5KBg2dhEMXEH7gk4p+v18J091Kw8mC6PZN7IHe7J52Ba1TWAZKDyr1ed9Zo7WUPnMrUNlDgOb5G/cDXkG37mu2wpFkU04A6lm3g4OCorJi1S2Z1pn5Fme1bxvc/eF1NAh8RxrNoHTx2e5XRiX+SJPHihS0ljLEyTZ7+4ZhkSMgPf5XPnT/mDM2OnspHtyyhrP/npZMFPoZpFpeNcX78a3mso+L4JT5+8FQ6qMeW5Zz6Q/oa/8ptuLNnTkkypOsMrNYlannLMJEXWx6W0Ig1hIdqRkQQzZ9wG4d88v9qGF396m3Vp6Rn+c9veqnLjXisajymVYsnK55GPMuqvcr02yHfa9c741Bd717hmYl1bJkG0CzkMshagLK+myHfddwAm67puWi3PDtlSvr3Nwb86/PNBeW23lazXHw98IBpUg3aJrdIUKDZECDN9GiA2MAbkLwTeFM2tmzvEbxe3XIp62w1L9DZ6yVA14iFmY7TqQ8JsgwMjXfVlH209PRbcr2r9Flrpb1bJggIB+OfrrRXFU+uZztxEKLoeXbxt3Yy+v8v/x+tL5/m6znbw3p6b5u+V9t1FSPYMDnsfM299hrQAznSlfiDUyOHiAf1IeCwjSqvQGw3BgulOTbUHH74UF/tp7Z8AOurH3inLVIdqzBBNF0x31Hi/2SFStddc0j8IKHoWWMywycMxoPPn6+/P0c3Ovk5vLpKtYXm9ET7HOYCBtC09zF5oaMqyCGCFCZ7j0kl/w7OOrDGhIWMmyXS7UHxdPZuso2S9qt+WsROt7Dhb/dmEj11ypgdSha9zNgPoFlkm4AJqus5QAvIo2GKyaFKxCgRI0MGlYjptYjJMCeNhil6NyViXqwqF5f3myz0GNQ2WGwp6L58EuL5aQiKC4ANBPdoBOn2PTVMs+Z7iordHssCwmoKCGt7n4G63rsc8uFP+oeP+ilId5BPASKaHSCWIAsCjQkjqjnQtQMPMcoGrTve9PZTkOziqbMCL7tt9TlEts8hF2fGpoN4rfBH0PKCrhE2vru+MmL3y3fnvz9/0Mn5KLrSbM3oXjl5yh0Qlz0sPmU/7M2fgSPMzpzxo2N+dyWgfmxVA/TmEY+jGlA/tqoBej16vfZ8vZ7AUkDjqBI9qD0flBLIfuCpUHC00L0kGRYj1gjup2TZvSxYD1FYE/INoIyadQGIZYYBjodJPJ8un3ntLVklOD3g9o7Vzo+ryiDYVurcNk0dHgm3leoWRhENeG2csTzxNr48Oocgz4foERVZ9nbl0/5pp7b/BURNo8hqI6nK7lJge0aRrrbWA1XTnfwPp2r6aBxQRq8D121cICjd9nF1m6l0m9JtB6Tb6suTM90m+Jy1L+VmyqPcFNl7T3alWD/W56x9ibXuzky2cdw7KrevLP086K9sEvJq/7imPpv4uZRaR5P1ZkXyVa6kWgsFWvXvUYX3SnlikuB7FK6xd/v878uC4t3Jl63FKw4qy80h6rvOJtrGHmXI2Zshp/FKjK3Igd7M6ZFSDiC9vmApwrYkckBN0VG4kCiDhyiD+g2vzRSAVNYBNUGnBf4ep23A1xStLWYiLkj4B9NjakZ49veSR9A6I6W27Ihl6brZ+GCQX7xrafHahxGy7JzYQRA+8nScLjUHTS4ess8cbfrEAMelkh+wKsBafbJb7bHa0LxQHgI7hOBDBNq18CimLcsgPP6gbymSL1vfogCs7BCHKCz7raHekfgXZ/dtI35vrbE+7J6oInTHELpkiNwyhK4ZTfeMymVLhwnBE+qBojCrGag3Lyt8LJqBojCRQ0n9bl1wt167u92dY13txK0aln0BylaN8zBhEWWUm8QJZ3xdXJ0DfKZbIm+MYPlHRoUlVlNFh5d5opyyQ6FPCq/5uxVZZm2LOKCvuUVcfbHc7eusvsw/6k6+0llKZymdtXdPXTXDat/67s174YR3zvheA0/a+HE2sH/cfDu/AacahJubeNRmOBt88dnDZjhdb7oHgmCH+3GovWvU7OG+MaYz9d1NXTbx/I64bGFl53Y4LYXZvV3cPvbDedn/5r33w+mubz3dEEe3GtDWazu4r7snDgTVry6wRvWt74nTVWd7wHrpe9+D3whHGTQ29dzobnKyMfe1HYLeR0E0K/4H3eloRxKIj3ziOC3ThCf1K28CLPBf -------------------------------------------------------------------------------- /Figures/omero-on-aws-ha.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/omero-on-aws-ha.jpg -------------------------------------------------------------------------------- /Figures/omero-on-aws-rw-fargate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/omero-on-aws-rw-fargate.jpg -------------------------------------------------------------------------------- /Figures/omero-on-aws-rw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/omero-on-aws-rw.jpg -------------------------------------------------------------------------------- /Figures/omero-server-blitz-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/omero-server-blitz-log.png -------------------------------------------------------------------------------- /Figures/omero-server-ip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/omero-server-ip.png -------------------------------------------------------------------------------- /Figures/omero-server-logs-cw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/omero-server-logs-cw.png -------------------------------------------------------------------------------- /Figures/omeroinsight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/omeroinsight.png -------------------------------------------------------------------------------- /Figures/omerowebimageurl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/omerowebimageurl.png -------------------------------------------------------------------------------- /Figures/securitygroup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/securitygroup.png -------------------------------------------------------------------------------- /Figures/storagegateway.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/digital-pathology-on-aws/f93ea9f92eb845a95430c23197b98e5b1ddf2f4b/Figures/storagegateway.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMERO2LBstackTLS_RW.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Metadata: 4 | 'AWS::CloudFormation::Interface': 5 | ParameterGroups: 6 | - Label: 7 | default: 'EFS Persistent Storage' 8 | Parameters: 9 | - OMEROStorageEFSNameTag 10 | - EFSBackup 11 | - EFSStorageArchiveAfter 12 | - KMSCMKId 13 | - Label: 14 | default: 'RDS Database' 15 | Parameters: 16 | - RDSDBInstanceSize 17 | - RDSDBStorage 18 | - RDSDStorageSize 19 | - RDSDBUserName 20 | - RDSDBBackupRetainInDays 21 | - RDSDBMultiAZ 22 | - Label: 23 | default: 'ECS' 24 | Parameters: 25 | - ECSContainerOnEC2 26 | - EC2KeyName 27 | - EC2InstanceType 28 | - NumberofECSEC2Instances 29 | - LoadBalancerAccessLogBucketName 30 | - CountofWebInstances 31 | - OMEROWebContainerCPUSize 32 | - OMEROWebContainerMemorySize 33 | - OMEROServerContainerCPUSize 34 | - OMEROServerContainerMemorySize 35 | - OMEROWebContainerImageParam 36 | - OMEROServerContainerImageParam 37 | - Label: 38 | default: 'Infrastructure' 39 | Parameters: 40 | - OMEROVPCID 41 | - DBECSPrivateSubnet1Id 42 | - DBECSPrivateSubnet2Id 43 | - LBPublicSubnet1Id 44 | - LBPublicSubnet2Id 45 | - CIDROMEROSecurityGroup 46 | - ExistingRoute53HostedZoneId 47 | - Route53FullDomainName 48 | 49 | Parameters: 50 | StackNamespace: 51 | Type: String 52 | Default: test 53 | OMEROVPCID: 54 | Description: ID of the VPC 55 | Type: AWS::EC2::VPC::Id 56 | DBECSPrivateSubnet1Id: 57 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 58 | Type: AWS::EC2::Subnet::Id 59 | DBECSPrivateSubnet2Id: 60 | Description: SubnetId, for Availability Zone 2 in the region in your VPC 61 | Type: AWS::EC2::Subnet::Id 62 | LBPublicSubnet1Id: 63 | Description: SubnetId, for Availability Zone 1 in the region in your VPC. The only one OMERO Server instance is deployed in this subnet. 64 | Type: AWS::EC2::Subnet::Id 65 | LBPublicSubnet2Id: 66 | Description: SubnetId, for Availability Zone 2 in the region in your VPC. None of OMERO Server instance is deployed in this subnet. 67 | Type: AWS::EC2::Subnet::Id 68 | CIDROMEROSecurityGroup: 69 | Type: String 70 | Default: '0.0.0.0/0' 71 | OMEROStorageEFSNameTag: 72 | Description: The name of the EFS volume 73 | Type: String 74 | MinLength: '1' 75 | Default: OMEROEFSvolume 76 | KMSCMKId: 77 | Description: The ID of the AWS KMS customer master key (CMK) to be used to protect the encrypted EFS and RDS storage. OPTIONAL if not specified, the default CMKs for Amazon EFS and RDS are used. 78 | Type: String 79 | EFSBackup: 80 | Type: String 81 | Description: whether enable EFS backup or not. EFS backup has extra associated cost. 82 | Default: ENABLED 83 | AllowedValues: [ENABLED, DISABLED] 84 | EFSStorageArchiveAfter: 85 | Type: String 86 | Description: A value that describes the period of time that a file is not accessed, after which it transitions to the IA storage class. 87 | Default: AFTER_90_DAYS 88 | AllowedValues: [AFTER_14_DAYS, AFTER_30_DAYS, AFTER_60_DAYS, AFTER_7_DAYS, AFTER_90_DAYS] 89 | RDSDBMultiAZ: 90 | Type: String 91 | Default: False 92 | Description: True or False for RDS Multiple Availability Zone 93 | RDSDBInstanceSize: 94 | Type: String 95 | Default: "db.t3.medium" 96 | RDSDBStorage: 97 | Type: String 98 | Default: "gp2" 99 | RDSDStorageSize: 100 | Type: Number 101 | Default: 20 102 | RDSDBUserName: 103 | Type: String 104 | Default: omero 105 | Description: OMERO Database User 106 | NoEcho: true 107 | RDSDBBackupRetainInDays: 108 | Type: Number 109 | Default: 30 110 | Description: The number of days for which automated backups are retained. Setting this parameter to a positive number (from 1 to 35) enables backups. Setting this parameter to 0 disables automated backups. 111 | LoadBalancerAccessLogBucketName: 112 | Type: String 113 | Default: ecs-loadbalancer-accesslog 114 | CountofWebInstances: 115 | Type: Number 116 | Default: 2 117 | Description: Number of OMERO Web containers 118 | OMEROServerContainerImageParam: 119 | Type: String 120 | Default: openmicroscopy/omero-server:latest 121 | OMEROWebContainerImageParam: 122 | Type: String 123 | Default: openmicroscopy/omero-web-standalone:latest 124 | OMEROWebContainerCPUSize: 125 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 126 | Type: Number 127 | Default: 2048 128 | AllowedValues: [256, 512, 1024, 2048, 4096] 129 | OMEROWebContainerMemorySize: 130 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 131 | Type: Number 132 | Default: 4096 133 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 134 | ECSContainerOnEC2: 135 | Type: String 136 | Default: N 137 | Description: will the ECS containers be hosted on ECS EC2 or Fargate launch type 138 | AllowedValues: [Y, N] 139 | EC2KeyName: 140 | Type: String 141 | Description: Name of an existing EC2 KeyPair to enable SSH access to the ECS EC2 instance hosting OMERO Server. OPTIONAL only for EC2 launch type. 142 | NumberofECSEC2Instances: 143 | Description: Number of EC2 instance to run container in ECS cluster. OPTIONAL only for EC2 lanuch type. 144 | Type: Number 145 | Default: 1 146 | EC2InstanceType: 147 | Description: ECS EC2 instance type. OPTIONAL only for EC2 launch type. 148 | Type: String 149 | Default: m4.xlarge 150 | AllowedValues: [t2.large, m3.large, 151 | m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, 152 | c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge, 153 | c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, 154 | r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] 155 | ConstraintDescription: Please choose a valid instance type. 156 | OMEROServerContainerCPUSize: 157 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 158 | Type: Number 159 | Default: 4096 160 | AllowedValues: [256, 512, 1024, 2048, 4096] 161 | OMEROServerContainerMemorySize: 162 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 163 | Type: Number 164 | Default: 10240 165 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 166 | ExistingRoute53HostedZoneId: 167 | Description: Existing HostedZone for Registered Domain used to validate SSL Certificate 168 | Type: AWS::Route53::HostedZone::Id 169 | Route53FullDomainName: 170 | Description: Enter the Fully Qualified Domain Name to validate SSL Certificate 171 | Type: String 172 | 173 | Resources: 174 | StorageStack: 175 | Type: 'AWS::CloudFormation::Stack' 176 | Properties: 177 | TemplateURL: https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROstorage.yaml 178 | Parameters: 179 | EFSNameTag: !Ref OMEROStorageEFSNameTag 180 | VPCID: !Ref OMEROVPCID 181 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 182 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 183 | CIDRblock4OMEROSecurityGroup: !Ref CIDROMEROSecurityGroup 184 | KMSCustomMasterKey: !Ref KMSCMKId 185 | EnableEFSBackup: !Ref EFSBackup 186 | EFSStorageInfrequentAcessAfter: !Ref EFSStorageArchiveAfter 187 | IsDBMultiAZ: !Ref RDSDBMultiAZ 188 | RDSDBInstanceClass: !Ref RDSDBInstanceSize 189 | RDSDBStorageType: !Ref RDSDBStorage 190 | RDSDBAllocatedStorage: !Ref RDSDStorageSize 191 | DBUser: !Ref RDSDBUserName 192 | RDSDBBackupRetentionDays: !Ref RDSDBBackupRetainInDays 193 | ECScontainerStack: 194 | Type: 'AWS::CloudFormation::Stack' 195 | Properties: 196 | TemplateURL: https://omero-on-aws.s3.us-west-1.amazonaws.com/OMEROonECS_ALBNLBwithTLS_RW.yaml 197 | Parameters: 198 | Namespace: !Ref StackNamespace 199 | VPCID: !Ref OMEROVPCID 200 | PublicSubnet1Id: !Ref LBPublicSubnet1Id 201 | PublicSubnet2Id: !Ref LBPublicSubnet2Id 202 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 203 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 204 | KeyName: !Ref EC2KeyName 205 | LBAccessLogBucketName: !Ref LoadBalancerAccessLogBucketName 206 | NumberofWebInstances: !Ref CountofWebInstances 207 | OMEROWebContainerCPU: !Ref OMEROWebContainerCPUSize 208 | OMEROWebContainerMemory: !Ref OMEROWebContainerMemorySize 209 | ContainerOnEC2: !Ref ECSContainerOnEC2 210 | InstanceType: !Ref EC2InstanceType 211 | NumberofEC2Instances: !Ref NumberofECSEC2Instances 212 | OMEROServerContainerCPU: !Ref OMEROServerContainerCPUSize 213 | OMEROServerContainerMemory: !Ref OMEROServerContainerMemorySize 214 | OMEROServerContainerImage: !Ref OMEROServerContainerImageParam 215 | OMEROWebContainerImage: !Ref OMEROWebContainerImageParam 216 | DBUser: !Ref RDSDBUserName 217 | ExistingHostedZoneId: !Ref ExistingRoute53HostedZoneId 218 | FullDomainName: !Ref Route53FullDomainName 219 | LBSecurityGroup: 220 | Fn::GetAtt: 221 | - StorageStack 222 | - Outputs.LBSecurityGroup 223 | EFSSecurityGroup: 224 | Fn::GetAtt: 225 | - StorageStack 226 | - Outputs.EFSSecurityGroup 227 | OmeroSecurityGroup: 228 | Fn::GetAtt: 229 | - StorageStack 230 | - Outputs.OmeroSecurityGroup 231 | EFSFileSystem: 232 | Fn::GetAtt: 233 | - StorageStack 234 | - Outputs.EFSFileSystemID 235 | RDSEndpointAddress: 236 | Fn::GetAtt: 237 | - StorageStack 238 | - Outputs.RDSEndpointAddress 239 | RDSDatabaseSecret: 240 | Fn::GetAtt: 241 | - StorageStack 242 | - Outputs.RDSDatabaseSecret 243 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMERO2LBstackTLS_RW_StorageGateway.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Metadata: 4 | 'AWS::CloudFormation::Interface': 5 | ParameterGroups: 6 | - Label: 7 | default: 'EFS Persistent Storage' 8 | Parameters: 9 | - OMEROStorageEFSNameTag 10 | - EFSBackup 11 | - EFSStorageArchiveAfter 12 | - KMSCMKId 13 | - Label: 14 | default: 'Storage Gateway' 15 | Parameters: 16 | - StorageS3FileGatewayIp 17 | - StorageS3BucketName 18 | - Label: 19 | default: 'RDS Database' 20 | Parameters: 21 | - RDSDBInstanceSize 22 | - RDSDBStorage 23 | - RDSDStorageSize 24 | - RDSDBUserName 25 | - RDSDBBackupRetainInDays 26 | - RDSDBMultiAZ 27 | - Label: 28 | default: 'ECS' 29 | Parameters: 30 | - EC2KeyName 31 | - EC2InstanceType 32 | - NumberofECSEC2Instances 33 | - LoadBalancerAccessLogBucketName 34 | - CountofWebInstances 35 | - OMEROWebContainerCPUSize 36 | - OMEROWebContainerMemorySize 37 | - OMEROServerContainerCPUSize 38 | - OMEROServerContainerMemorySize 39 | - OMEROWebContainerImageParam 40 | - OMEROServerContainerImageParam 41 | - Label: 42 | default: 'Infrastructure' 43 | Parameters: 44 | - OMEROVPCID 45 | - DBECSPrivateSubnet1Id 46 | - DBECSPrivateSubnet2Id 47 | - LBPublicSubnet1Id 48 | - LBPublicSubnet2Id 49 | - CIDROMEROSecurityGroup 50 | - ExistingRoute53HostedZoneId 51 | - Route53FullDomainName 52 | 53 | Parameters: 54 | StackNamespace: 55 | Type: String 56 | Default: test 57 | OMEROVPCID: 58 | Description: ID of the VPC 59 | Type: AWS::EC2::VPC::Id 60 | DBECSPrivateSubnet1Id: 61 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 62 | Type: AWS::EC2::Subnet::Id 63 | DBECSPrivateSubnet2Id: 64 | Description: SubnetId, for Availability Zone 2 in the region in your VPC 65 | Type: AWS::EC2::Subnet::Id 66 | LBPublicSubnet1Id: 67 | Description: SubnetId, for Availability Zone 1 in the region in your VPC. The only one OMERO Server instance is deployed in this subnet. 68 | Type: AWS::EC2::Subnet::Id 69 | LBPublicSubnet2Id: 70 | Description: SubnetId, for Availability Zone 2 in the region in your VPC. None of OMERO Server instance is deployed in this subnet. 71 | Type: AWS::EC2::Subnet::Id 72 | CIDROMEROSecurityGroup: 73 | Type: String 74 | Default: '0.0.0.0/0' 75 | OMEROStorageEFSNameTag: 76 | Description: The name of the EFS volume 77 | Type: String 78 | MinLength: '1' 79 | Default: OMEROEFSvolume 80 | KMSCMKId: 81 | Description: The ID of the AWS KMS customer master key (CMK) to be used to protect the encrypted EFS and RDS storage. OPTIONAL if not specified, the default CMKs for Amazon EFS and RDS are used. 82 | Type: String 83 | EFSBackup: 84 | Type: String 85 | Description: whether enable EFS backup or not. EFS backup has extra associated cost. 86 | Default: ENABLED 87 | AllowedValues: [ENABLED, DISABLED] 88 | EFSStorageArchiveAfter: 89 | Type: String 90 | Description: A value that describes the period of time that a file is not accessed, after which it transitions to the IA storage class. 91 | Default: AFTER_90_DAYS 92 | AllowedValues: [AFTER_14_DAYS, AFTER_30_DAYS, AFTER_60_DAYS, AFTER_7_DAYS, AFTER_90_DAYS] 93 | RDSDBMultiAZ: 94 | Type: String 95 | Default: False 96 | Description: True or False for RDS Multiple Availability Zone 97 | RDSDBInstanceSize: 98 | Type: String 99 | Default: "db.t3.medium" 100 | RDSDBStorage: 101 | Type: String 102 | Default: "gp2" 103 | RDSDStorageSize: 104 | Type: Number 105 | Default: 20 106 | RDSDBUserName: 107 | Type: String 108 | Default: omero 109 | Description: OMERO Database User 110 | NoEcho: true 111 | RDSDBBackupRetainInDays: 112 | Type: Number 113 | Default: 30 114 | Description: The number of days for which automated backups are retained. Setting this parameter to a positive number (from 1 to 35) enables backups. Setting this parameter to 0 disables automated backups. 115 | LoadBalancerAccessLogBucketName: 116 | Type: String 117 | Default: ecs-loadbalancer-accesslog 118 | CountofWebInstances: 119 | Type: Number 120 | Default: 2 121 | Description: Number of OMERO Web containers 122 | OMEROServerContainerImageParam: 123 | Type: String 124 | Default: openmicroscopy/omero-server:latest 125 | OMEROWebContainerImageParam: 126 | Type: String 127 | Default: openmicroscopy/omero-web-standalone:latest 128 | OMEROWebContainerCPUSize: 129 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 130 | Type: Number 131 | Default: 2048 132 | AllowedValues: [256, 512, 1024, 2048, 4096] 133 | OMEROWebContainerMemorySize: 134 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 135 | Type: Number 136 | Default: 4096 137 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 138 | EC2KeyName: 139 | Type: String 140 | Description: Name of an existing EC2 KeyPair to enable SSH access to the ECS EC2 instance hosting OMERO Server. OPTIONAL only for EC2 launch type. 141 | NumberofECSEC2Instances: 142 | Description: Number of EC2 instance to run container in ECS cluster. OPTIONAL only for EC2 lanuch type. 143 | Type: Number 144 | Default: 1 145 | EC2InstanceType: 146 | Description: ECS EC2 instance type. OPTIONAL only for EC2 launch type. 147 | Type: String 148 | Default: m4.xlarge 149 | AllowedValues: [t2.large, m3.large, 150 | m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, 151 | c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge, 152 | c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, 153 | r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] 154 | ConstraintDescription: Please choose a valid instance type. 155 | OMEROServerContainerCPUSize: 156 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 157 | Type: Number 158 | Default: 4096 159 | AllowedValues: [256, 512, 1024, 2048, 4096] 160 | OMEROServerContainerMemorySize: 161 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 162 | Type: Number 163 | Default: 8192 164 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 165 | ExistingRoute53HostedZoneId: 166 | Description: Existing HostedZone for Registered Domain used to validate SSL Certificate 167 | Type: AWS::Route53::HostedZone::Id 168 | Route53FullDomainName: 169 | Description: Enter the Fully Qualified Domain Name to validate SSL Certificate 170 | Type: String 171 | StorageS3FileGatewayIp: 172 | Type: String 173 | Description: The public IP address of the EC2 instance for S3 file gateway 174 | StorageS3BucketName: 175 | Type: String 176 | Description: The S3 bucket name for s3 file gateway 177 | 178 | Resources: 179 | StorageStack: 180 | Type: 'AWS::CloudFormation::Stack' 181 | Properties: 182 | TemplateURL: https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROstorage.yaml 183 | Parameters: 184 | EFSNameTag: !Ref OMEROStorageEFSNameTag 185 | VPCID: !Ref OMEROVPCID 186 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 187 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 188 | CIDRblock4OMEROSecurityGroup: !Ref CIDROMEROSecurityGroup 189 | KMSCustomMasterKey: !Ref KMSCMKId 190 | EnableEFSBackup: !Ref EFSBackup 191 | EFSStorageInfrequentAcessAfter: !Ref EFSStorageArchiveAfter 192 | IsDBMultiAZ: !Ref RDSDBMultiAZ 193 | RDSDBInstanceClass: !Ref RDSDBInstanceSize 194 | RDSDBStorageType: !Ref RDSDBStorage 195 | RDSDBAllocatedStorage: !Ref RDSDStorageSize 196 | DBUser: !Ref RDSDBUserName 197 | RDSDBBackupRetentionDays: !Ref RDSDBBackupRetainInDays 198 | ECScontainerStack: 199 | Type: 'AWS::CloudFormation::Stack' 200 | Properties: 201 | TemplateURL: https://omero-on-aws.s3.us-west-1.amazonaws.com/OMEROonECS_ALBNLBwithTLS_RW_StorageGateway.yaml 202 | Parameters: 203 | Namespace: !Ref StackNamespace 204 | VPCID: !Ref OMEROVPCID 205 | PublicSubnet1Id: !Ref LBPublicSubnet1Id 206 | PublicSubnet2Id: !Ref LBPublicSubnet2Id 207 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 208 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 209 | KeyName: !Ref EC2KeyName 210 | LBAccessLogBucketName: !Ref LoadBalancerAccessLogBucketName 211 | NumberofWebInstances: !Ref CountofWebInstances 212 | OMEROWebContainerCPU: !Ref OMEROWebContainerCPUSize 213 | OMEROWebContainerMemory: !Ref OMEROWebContainerMemorySize 214 | InstanceType: !Ref EC2InstanceType 215 | NumberofEC2Instances: !Ref NumberofECSEC2Instances 216 | OMEROServerContainerCPU: !Ref OMEROServerContainerCPUSize 217 | OMEROServerContainerMemory: !Ref OMEROServerContainerMemorySize 218 | OMEROServerContainerImage: !Ref OMEROServerContainerImageParam 219 | OMEROWebContainerImage: !Ref OMEROWebContainerImageParam 220 | S3BucketName: !Ref StorageS3BucketName 221 | S3FileGatewayIp: !Ref StorageS3FileGatewayIp 222 | DBUser: !Ref RDSDBUserName 223 | ExistingHostedZoneId: !Ref ExistingRoute53HostedZoneId 224 | FullDomainName: !Ref Route53FullDomainName 225 | LBSecurityGroup: 226 | Fn::GetAtt: 227 | - StorageStack 228 | - Outputs.LBSecurityGroup 229 | EFSSecurityGroup: 230 | Fn::GetAtt: 231 | - StorageStack 232 | - Outputs.EFSSecurityGroup 233 | OmeroSecurityGroup: 234 | Fn::GetAtt: 235 | - StorageStack 236 | - Outputs.OmeroSecurityGroup 237 | EFSFileSystem: 238 | Fn::GetAtt: 239 | - StorageStack 240 | - Outputs.EFSFileSystemID 241 | RDSEndpointAddress: 242 | Fn::GetAtt: 243 | - StorageStack 244 | - Outputs.RDSEndpointAddress 245 | RDSDatabaseSecret: 246 | Fn::GetAtt: 247 | - StorageStack 248 | - Outputs.RDSDatabaseSecret 249 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMERONetworkInfra.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Description: This template deploys a VPC, with a pair of public and private subnets spread 4 | across two Availability Zones. It deploys an internet gateway, with a default 5 | route on the public subnets. It deploys a pair of NAT gateways (one in each AZ), 6 | and default routes for them in the private subnets. 7 | 8 | Metadata: 9 | 'AWS::CloudFormation::Interface': 10 | ParameterGroups: 11 | - Label: 12 | default: 'VPC Flow Logs Parameters' 13 | Parameters: 14 | - AddVPCFlowLog 15 | - VPCFlowLogTrafficType 16 | - RetentionInDays 17 | 18 | Parameters: 19 | EnvironmentName: 20 | Description: An environment name that is prefixed to resource names 21 | Type: String 22 | Default: OMERO 23 | 24 | VpcCIDR: 25 | Description: Please enter the IP range (CIDR notation) for this VPC 26 | Type: String 27 | Default: 10.192.0.0/16 28 | 29 | PublicSubnet1CIDR: 30 | Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone 31 | Type: String 32 | Default: 10.192.10.0/24 33 | 34 | PublicSubnet2CIDR: 35 | Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone 36 | Type: String 37 | Default: 10.192.11.0/24 38 | 39 | PrivateSubnet1CIDR: 40 | Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone 41 | Type: String 42 | Default: 10.192.20.0/24 43 | 44 | PrivateSubnet2CIDR: 45 | Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone 46 | Type: String 47 | Default: 10.192.21.0/24 48 | 49 | AddVPCFlowLog: 50 | Type: String 51 | Default: false 52 | AllowedValues: 53 | - true 54 | - false 55 | 56 | VPCFlowLogTrafficType: 57 | Description: 'The type of traffic to log.' 58 | Type: String 59 | Default: ALL 60 | AllowedValues: 61 | - ACCEPT 62 | - REJECT 63 | - ALL 64 | 65 | RetentionInDays: 66 | Description: 'Specifies the number of days you want to retain log events.' 67 | Type: Number 68 | Default: 14 69 | AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653] 70 | 71 | Conditions: 72 | CreateVPCFlowLog: !Equals 73 | - true 74 | - !Ref 'AddVPCFlowLog' 75 | 76 | Resources: 77 | VPC: 78 | Type: AWS::EC2::VPC 79 | Properties: 80 | CidrBlock: !Ref VpcCIDR 81 | EnableDnsSupport: true 82 | EnableDnsHostnames: true 83 | Tags: 84 | - Key: Name 85 | Value: !Ref EnvironmentName 86 | 87 | VPCFlowLog: 88 | Condition: CreateVPCFlowLog 89 | Type: AWS::EC2::FlowLog 90 | Properties: 91 | DeliverLogsPermissionArn: !GetAtt FlowLogRole.Arn 92 | LogGroupName: !Ref VPCFlowLogsGroup 93 | ResourceId: !Ref VPC 94 | ResourceType: VPC 95 | TrafficType: !Ref VPCFlowLogTrafficType 96 | 97 | VPCFlowLogsGroup: 98 | Type: 'AWS::Logs::LogGroup' 99 | Properties: 100 | RetentionInDays: !Ref RetentionInDays 101 | 102 | FlowLogRole: 103 | Type: 'AWS::IAM::Role' 104 | Properties: 105 | AssumeRolePolicyDocument: 106 | Version: '2012-10-17' 107 | Statement: 108 | - Effect: Allow 109 | Principal: 110 | Service: 'vpc-flow-logs.amazonaws.com' 111 | Action: 'sts:AssumeRole' 112 | Policies: 113 | - PolicyName: 'flowlogs-policy' 114 | PolicyDocument: 115 | Version: '2012-10-17' 116 | Statement: 117 | - Effect: Allow 118 | Action: 119 | - 'logs:CreateLogStream' 120 | - 'logs:PutLogEvents' 121 | - 'logs:DescribeLogGroups' 122 | - 'logs:DescribeLogStreams' 123 | Resource: !GetAtt 'VPCFlowLogsGroup.Arn' 124 | 125 | InternetGateway: 126 | Type: AWS::EC2::InternetGateway 127 | Properties: 128 | Tags: 129 | - Key: Name 130 | Value: !Ref EnvironmentName 131 | 132 | InternetGatewayAttachment: 133 | Type: AWS::EC2::VPCGatewayAttachment 134 | Properties: 135 | InternetGatewayId: !Ref InternetGateway 136 | VpcId: !Ref VPC 137 | 138 | PublicSubnet1: 139 | Type: AWS::EC2::Subnet 140 | Properties: 141 | VpcId: !Ref VPC 142 | AvailabilityZone: !Select [ 0, !GetAZs '' ] 143 | CidrBlock: !Ref PublicSubnet1CIDR 144 | MapPublicIpOnLaunch: true 145 | Tags: 146 | - Key: Name 147 | Value: !Sub ${EnvironmentName} Public Subnet (AZ1) 148 | 149 | PublicSubnet2: 150 | Type: AWS::EC2::Subnet 151 | Properties: 152 | VpcId: !Ref VPC 153 | AvailabilityZone: !Select [ 1, !GetAZs '' ] 154 | CidrBlock: !Ref PublicSubnet2CIDR 155 | MapPublicIpOnLaunch: true 156 | Tags: 157 | - Key: Name 158 | Value: !Sub ${EnvironmentName} Public Subnet (AZ2) 159 | 160 | PrivateSubnet1: 161 | Type: AWS::EC2::Subnet 162 | Properties: 163 | VpcId: !Ref VPC 164 | AvailabilityZone: !Select [ 0, !GetAZs '' ] 165 | CidrBlock: !Ref PrivateSubnet1CIDR 166 | MapPublicIpOnLaunch: false 167 | Tags: 168 | - Key: Name 169 | Value: !Sub ${EnvironmentName} Private Subnet (AZ1) 170 | 171 | PrivateSubnet2: 172 | Type: AWS::EC2::Subnet 173 | Properties: 174 | VpcId: !Ref VPC 175 | AvailabilityZone: !Select [ 1, !GetAZs '' ] 176 | CidrBlock: !Ref PrivateSubnet2CIDR 177 | MapPublicIpOnLaunch: false 178 | Tags: 179 | - Key: Name 180 | Value: !Sub ${EnvironmentName} Private Subnet (AZ2) 181 | 182 | NatGateway1EIP: 183 | Type: AWS::EC2::EIP 184 | DependsOn: InternetGatewayAttachment 185 | Properties: 186 | Domain: vpc 187 | 188 | NatGateway2EIP: 189 | Type: AWS::EC2::EIP 190 | DependsOn: InternetGatewayAttachment 191 | Properties: 192 | Domain: vpc 193 | 194 | NatGateway1: 195 | Type: AWS::EC2::NatGateway 196 | Properties: 197 | AllocationId: !GetAtt NatGateway1EIP.AllocationId 198 | SubnetId: !Ref PublicSubnet1 199 | 200 | NatGateway2: 201 | Type: AWS::EC2::NatGateway 202 | Properties: 203 | AllocationId: !GetAtt NatGateway2EIP.AllocationId 204 | SubnetId: !Ref PublicSubnet2 205 | 206 | PublicRouteTable: 207 | Type: AWS::EC2::RouteTable 208 | Properties: 209 | VpcId: !Ref VPC 210 | Tags: 211 | - Key: Name 212 | Value: !Sub ${EnvironmentName} Public Routes 213 | 214 | DefaultPublicRoute: 215 | Type: AWS::EC2::Route 216 | DependsOn: InternetGatewayAttachment 217 | Properties: 218 | RouteTableId: !Ref PublicRouteTable 219 | DestinationCidrBlock: 0.0.0.0/0 220 | GatewayId: !Ref InternetGateway 221 | 222 | PublicSubnet1RouteTableAssociation: 223 | Type: AWS::EC2::SubnetRouteTableAssociation 224 | Properties: 225 | RouteTableId: !Ref PublicRouteTable 226 | SubnetId: !Ref PublicSubnet1 227 | 228 | PublicSubnet2RouteTableAssociation: 229 | Type: AWS::EC2::SubnetRouteTableAssociation 230 | Properties: 231 | RouteTableId: !Ref PublicRouteTable 232 | SubnetId: !Ref PublicSubnet2 233 | 234 | 235 | PrivateRouteTable1: 236 | Type: AWS::EC2::RouteTable 237 | Properties: 238 | VpcId: !Ref VPC 239 | Tags: 240 | - Key: Name 241 | Value: !Sub ${EnvironmentName} Private Routes (AZ1) 242 | 243 | DefaultPrivateRoute1: 244 | Type: AWS::EC2::Route 245 | Properties: 246 | RouteTableId: !Ref PrivateRouteTable1 247 | DestinationCidrBlock: 0.0.0.0/0 248 | NatGatewayId: !Ref NatGateway1 249 | 250 | PrivateSubnet1RouteTableAssociation: 251 | Type: AWS::EC2::SubnetRouteTableAssociation 252 | Properties: 253 | RouteTableId: !Ref PrivateRouteTable1 254 | SubnetId: !Ref PrivateSubnet1 255 | 256 | PrivateRouteTable2: 257 | Type: AWS::EC2::RouteTable 258 | Properties: 259 | VpcId: !Ref VPC 260 | Tags: 261 | - Key: Name 262 | Value: !Sub ${EnvironmentName} Private Routes (AZ2) 263 | 264 | DefaultPrivateRoute2: 265 | Type: AWS::EC2::Route 266 | Properties: 267 | RouteTableId: !Ref PrivateRouteTable2 268 | DestinationCidrBlock: 0.0.0.0/0 269 | NatGatewayId: !Ref NatGateway2 270 | 271 | PrivateSubnet2RouteTableAssociation: 272 | Type: AWS::EC2::SubnetRouteTableAssociation 273 | Properties: 274 | RouteTableId: !Ref PrivateRouteTable2 275 | SubnetId: !Ref PrivateSubnet2 276 | 277 | Outputs: 278 | VPC: 279 | Description: A reference to the created VPC 280 | Value: !Ref VPC 281 | 282 | PublicSubnets: 283 | Description: A list of the public subnets 284 | Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2 ]] 285 | 286 | PrivateSubnets: 287 | Description: A list of the private subnets 288 | Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]] 289 | 290 | PublicSubnet1: 291 | Description: A reference to the public subnet in the 1st Availability Zone 292 | Value: !Ref PublicSubnet1 293 | 294 | PublicSubnet2: 295 | Description: A reference to the public subnet in the 2nd Availability Zone 296 | Value: !Ref PublicSubnet2 297 | 298 | PrivateSubnet1: 299 | Description: A reference to the private subnet in the 1st Availability Zone 300 | Value: !Ref PrivateSubnet1 301 | 302 | PrivateSubnet2: 303 | Description: A reference to the private subnet in the 2nd Availability Zone 304 | Value: !Ref PrivateSubnet2 305 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMERO_DataSync.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | Description: Datasync Stack to deploy EFS, DataSync Locations and Task 3 | 4 | Parameters: 5 | S3BucketName: 6 | Description: Bucket Name 7 | Type: String 8 | OMEROSecurityGroup: 9 | Description: Security group for OMERO to access EFS 10 | Type: AWS::EC2::SecurityGroup::Id 11 | EFSSubnetId: 12 | Description: Please provide EFS Subnet Id 13 | Type: AWS::EC2::Subnet::Id 14 | EFSFileSystemId: 15 | Description: Provide EFS File System Arn 16 | Type: String 17 | S3Path: 18 | Type: String 19 | Default: / 20 | Description: This subdirectory in Amazon S3 is used to read data from the S3 source location. 21 | EFSFolder: 22 | Type: String 23 | Default: / 24 | Description: This subdirectory in the EFS file system is used to write data to the EFS destination 25 | 26 | Resources: 27 | SourceLocationS3Bucket: 28 | Type: AWS::S3::Bucket 29 | Properties: 30 | BucketName: !Join 31 | - '-' 32 | - - !Ref S3BucketName 33 | - !Ref AWS::AccountId 34 | - !Ref AWS::Region 35 | PublicAccessBlockConfiguration: 36 | BlockPublicAcls: True 37 | BlockPublicPolicy: True 38 | IgnorePublicAcls: True 39 | RestrictPublicBuckets: True 40 | BucketEncryption: 41 | ServerSideEncryptionConfiguration: 42 | - ServerSideEncryptionByDefault: 43 | SSEAlgorithm: AES256 44 | VersioningConfiguration: 45 | Status: Enabled 46 | SourceLocationS3BuckerRole: 47 | Type: AWS::IAM::Role 48 | Properties: 49 | AssumeRolePolicyDocument: 50 | Statement: 51 | - Action: 52 | - sts:AssumeRole 53 | Effect: Allow 54 | Principal: 55 | Service: datasync.amazonaws.com 56 | Version: '2012-10-17' 57 | Policies: 58 | - PolicyName: datasync-s3role 59 | PolicyDocument: 60 | Statement: 61 | - Action: 62 | - s3:GetBucketLocation 63 | - s3:ListBucket 64 | - s3:ListBucketMultipartUploads 65 | Effect: Allow 66 | Resource: 67 | Fn::GetAtt: 68 | - SourceLocationS3Bucket 69 | - Arn 70 | - Action: 71 | - s3:AbortMultipartUpload 72 | - s3:DeleteObject 73 | - s3:GetObject 74 | - s3:ListMultipartUploadParts 75 | - s3:PutObjectTagging 76 | - s3:GetObjectTagging 77 | - s3:PutObject 78 | Effect: Allow 79 | Resource: 80 | Fn::Join: 81 | - "" 82 | - - Fn::GetAtt: 83 | - SourceLocationS3Bucket 84 | - Arn 85 | - /* 86 | Version: "2012-10-17" 87 | DataSyncLogGroup: 88 | Type: AWS::Logs::LogGroup 89 | Properties: 90 | LogGroupName: "/aws/datasync/omero/datasync" 91 | RetentionInDays: 7 92 | OmeroLocationS3: 93 | Type: AWS::DataSync::LocationS3 94 | Properties: 95 | S3BucketArn: !GetAtt SourceLocationS3Bucket.Arn 96 | S3Config: 97 | BucketAccessRoleArn: !GetAtt SourceLocationS3BuckerRole.Arn 98 | S3StorageClass: STANDARD 99 | Subdirectory: !Ref S3Path 100 | OmeroLocationEFS: 101 | Type: AWS::DataSync::LocationEFS 102 | DependsOn: 103 | - OmeroLocationS3 104 | - DataSyncLogGroup 105 | Properties: 106 | Ec2Config: 107 | SecurityGroupArns: 108 | - !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/${OMEROSecurityGroup} 109 | SubnetArn: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:subnet/${EFSSubnetId} 110 | EfsFilesystemArn: !Sub arn:aws:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/${EFSFileSystemId} 111 | Subdirectory: !Ref EFSFolder 112 | OmeroTask: 113 | Type: AWS::DataSync::Task 114 | DependsOn: 115 | - OmeroLocationS3 116 | - OmeroLocationEFS 117 | - DataSyncLogGroup 118 | Properties: 119 | SourceLocationArn: !Ref OmeroLocationS3 120 | DestinationLocationArn: !Ref OmeroLocationEFS 121 | CloudWatchLogGroupArn: !Select [0, !Split [':*', !GetAtt DataSyncLogGroup.Arn ]] 122 | Schedule: 123 | ScheduleExpression: "cron(0 * * * ? *)" 124 | Options: 125 | LogLevel: "TRANSFER" 126 | Atime: "NONE" 127 | Mtime: "NONE" 128 | PosixPermissions: "NONE" 129 | PreserveDeletedFiles: "PRESERVE" 130 | VerifyMode: "ONLY_FILES_TRANSFERRED" 131 | 132 | 133 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMEROonECS_ALBNLBwithTLS_RW.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | 3 | Parameters: 4 | Namespace: 5 | Description: A string of 4-20 lowercase letters and digits, starting with a letter. Included in resource names, allowing multiple deployments. 6 | Default: monai 7 | Type: String 8 | AllowedPattern: "^[a-z]{1}[a-z0-9]{3,19}$" 9 | ConstraintDescription: Between 4-20 letters and digits, starting with a letter 10 | VPCID: 11 | Description: ID of the VPC 12 | Type: AWS::EC2::VPC::Id 13 | PublicSubnet1Id: 14 | Description: SubnetId, for Availability Zone 1 in the region in your VPC. The only one OMERO Server instance is deployed in this subnet. 15 | Type: AWS::EC2::Subnet::Id 16 | PublicSubnet2Id: 17 | Description: SubnetId, for Availability Zone 2 in the region in your VPC. None of OMERO Server instance is deployed in this subnet. 18 | Type: AWS::EC2::Subnet::Id 19 | PrivateSubnet1Id: 20 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 21 | Type: AWS::EC2::Subnet::Id 22 | PrivateSubnet2Id: 23 | Description: SubnetId, for Availability Zone 2 in the region in your VPC 24 | Type: AWS::EC2::Subnet::Id 25 | LBSecurityGroup: 26 | Description: Security group for Application Load Balancer 27 | Type: AWS::EC2::SecurityGroup::Id 28 | OmeroSecurityGroup: 29 | Description: Security group for OMERO web and service containers 30 | Type: AWS::EC2::SecurityGroup::Id 31 | EFSSecurityGroup: 32 | Description: Security group for EFS 33 | Type: AWS::EC2::SecurityGroup::Id 34 | EFSFileSystem: 35 | Description: The ID of the EFS volume 36 | Type: String 37 | LBAccessLogBucketName: 38 | Type: String 39 | Default: lb-accesslog 40 | RDSEndpointAddress: 41 | Type: String 42 | Description: The RDS database endpoinst address 43 | NumberofWebInstances: 44 | Type: Number 45 | Default: 2 46 | OMEROWebContainerCPU: 47 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 48 | Type: Number 49 | Default: 2048 50 | AllowedValues: [256, 512, 1024, 2048, 4096] 51 | OMEROWebContainerMemory: 52 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 53 | Type: Number 54 | Default: 4096 55 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 56 | OMEROServerContainerImage: 57 | Type: String 58 | Default: openmicroscopy/omero-server:latest 59 | OMEROWebContainerImage: 60 | Type: String 61 | Default: openmicroscopy/omero-web-standalone:latest 62 | ContainerOnEC2: 63 | Type: String 64 | Default: N 65 | Description: will the containers be hosted on ECS EC2 or Fargate launch type 66 | AllowedValues: [Y, N] 67 | LatestAmiId: 68 | Type: 'AWS::SSM::Parameter::Value' 69 | Default: '/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id' 70 | KeyName: 71 | Type: String 72 | Description: Name of an existing EC2 KeyPair to enable SSH access to the EC2 instances. OPTIONAL only for EC2 launch type. 73 | InstanceType: 74 | Description: EC2 instance type. OPTIONAL only for EC2 launch type. 75 | Type: String 76 | Default: m4.xlarge 77 | AllowedValues: [t2.large, m3.large, 78 | m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, 79 | c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge, 80 | c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, 81 | r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] 82 | ConstraintDescription: Please choose a valid instance type. 83 | NumberofEC2Instances: 84 | Description: Number of EC2 instance to run container in ECS cluster. OPTIONAL only for EC2 lanuch type. 85 | Type: Number 86 | Default: 3 87 | OMEROServerContainerCPU: 88 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 89 | Type: Number 90 | Default: 4096 91 | AllowedValues: [256, 512, 1024, 2048, 4096] 92 | OMEROServerContainerMemory: 93 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 94 | Type: Number 95 | Default: 10240 96 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 97 | DBUser: 98 | Type: String 99 | Default: omero 100 | Description: OMERO Database User 101 | NoEcho: true 102 | RDSDatabaseSecret: 103 | Type: String 104 | Description: OMERO Database Password 105 | Default: RDSDatabaseSecret 106 | ExistingHostedZoneId: 107 | Description: Existing HostedZone for Registered Domain used for ACM Certificate 108 | Type: AWS::Route53::HostedZone::Id 109 | FullDomainName: 110 | Description: Enter the Fully Qualified Domain Nanme for ACM Certificate 111 | Type: String 112 | 113 | Conditions: 114 | runContainerOnEC2: !Equals [ !Ref 'ContainerOnEC2', 'Y' ] 115 | 116 | Mappings: 117 | RegionELBAccountIdMap: 118 | us-east-1: 119 | AccountId: '127311923021' 120 | us-west-1: 121 | AccountId: '027434742980' 122 | us-west-2: 123 | AccountId: '797873946194' 124 | eu-west-1: 125 | AccountId: '156460612806' 126 | ap-northeast-1: 127 | AccountId: '582318560864' 128 | ap-northeast-2: 129 | AccountId: '600734575887' 130 | ap-southeast-1: 131 | AccountId: '114774131450' 132 | ap-southeast-2: 133 | AccountId: '783225319266' 134 | ap-south-1: 135 | AccountId: '718504428378' 136 | us-east-2: 137 | AccountId: '033677994240' 138 | sa-east-1: 139 | AccountId: '507241528517' 140 | cn-north-1: 141 | AccountId: '638102146993' 142 | eu-central-1: 143 | AccountId: '054676820928' 144 | 145 | Resources: 146 | CloudMap: 147 | Type: AWS::ServiceDiscovery::PrivateDnsNamespace 148 | Properties: 149 | Description: Service Map for OMERO ECS deployment 150 | Name: !Sub ${AWS::StackName}.ecscloudmap.org 151 | Vpc: !Ref VPCID 152 | OmerowebServiceDiscoveryEntry: 153 | Type: AWS::ServiceDiscovery::Service 154 | Properties: 155 | Description: '"omeroweb" service discovery entry in Cloud Map' 156 | DnsConfig: 157 | DnsRecords: 158 | - TTL: 60 159 | Type: A 160 | RoutingPolicy: MULTIVALUE 161 | HealthCheckCustomConfig: 162 | FailureThreshold: 1 163 | Name: omeroweb 164 | NamespaceId: !Ref 'CloudMap' 165 | OmeroserverServiceDiscoveryEntry: 166 | Type: AWS::ServiceDiscovery::Service 167 | Properties: 168 | Description: '"omeroserver" service discovery entry in Cloud Map' 169 | DnsConfig: 170 | DnsRecords: 171 | - TTL: 60 172 | Type: A 173 | RoutingPolicy: MULTIVALUE 174 | HealthCheckCustomConfig: 175 | FailureThreshold: 1 176 | Name: omeroserver 177 | NamespaceId: !Ref 'CloudMap' 178 | 179 | OMEROECSCluster: 180 | Type: AWS::ECS::Cluster 181 | Properties: 182 | ClusterName: !Sub ${AWS::StackName}-OMEROECSCluster 183 | ClusterSettings: 184 | - Name: containerInsights 185 | Value: enabled 186 | Tags: 187 | - Key: project 188 | Value: omero-on-aws 189 | OMEROLoadBalancer: 190 | DependsOn: 191 | - LBAccessLogBucket 192 | - LBAccessLogBucketPolicy 193 | Type: AWS::ElasticLoadBalancingV2::LoadBalancer 194 | Properties: 195 | LoadBalancerAttributes: 196 | - Key: load_balancing.cross_zone.enabled 197 | Value: "true" 198 | Scheme: internet-facing 199 | Subnets: 200 | - !Ref 'PublicSubnet1Id' 201 | - !Ref 'PublicSubnet2Id' 202 | SecurityGroups: 203 | - !Ref LBSecurityGroup 204 | Tags: 205 | - Key: project 206 | Value: omero-on-aws 207 | Type: application 208 | LoadBalancerAttributes: 209 | - Key: access_logs.s3.enabled 210 | Value: true 211 | - Key: access_logs.s3.bucket 212 | Value: !Join 213 | - '-' 214 | - - !Ref LBAccessLogBucketName 215 | - !Ref Namespace 216 | - !Ref AWS::AccountId 217 | OMERONetworkLoadBalancer: 218 | DependsOn: 219 | - LBAccessLogBucket 220 | - LBAccessLogBucketPolicy 221 | Type: AWS::ElasticLoadBalancingV2::LoadBalancer 222 | Properties: 223 | Scheme: internet-facing 224 | Subnets: 225 | - !Ref 'PublicSubnet1Id' 226 | - !Ref 'PublicSubnet2Id' 227 | Tags: 228 | - Key: project 229 | Value: omero-on-aws 230 | Type: network 231 | LoadBalancerAttributes: 232 | - Key: access_logs.s3.enabled 233 | Value: true 234 | - Key: access_logs.s3.bucket 235 | Value: !Join 236 | - '-' 237 | - - !Ref LBAccessLogBucketName 238 | - !Ref Namespace 239 | - !Ref AWS::AccountId 240 | LBAccessLogBucket: 241 | Type: AWS::S3::Bucket 242 | Properties: 243 | BucketName: !Join 244 | - '-' 245 | - - !Ref LBAccessLogBucketName 246 | - !Ref Namespace 247 | - !Ref AWS::AccountId 248 | BucketEncryption: 249 | ServerSideEncryptionConfiguration: 250 | - ServerSideEncryptionByDefault: 251 | SSEAlgorithm: AES256 252 | VersioningConfiguration: 253 | Status: Enabled 254 | LBAccessLogBucketPolicy: 255 | Type: AWS::S3::BucketPolicy 256 | Properties: 257 | Bucket: !Ref LBAccessLogBucket 258 | PolicyDocument: 259 | Statement: 260 | - Action: 261 | - 's3:PutObject' 262 | Effect: Allow 263 | Resource: 264 | - !Sub '${LBAccessLogBucket.Arn}/*' 265 | Principal: 266 | AWS: !FindInMap [RegionELBAccountIdMap, !Ref 'AWS::Region', AccountId] 267 | - Action: 268 | - 's3:PutObject' 269 | Effect: Allow 270 | Resource: 271 | - !Sub '${LBAccessLogBucket.Arn}/*' 272 | Principal: 273 | Service: delivery.logs.amazonaws.com 274 | Condition: 275 | StringEquals: 276 | s3:x-amz-acl: bucket-owner-full-control 277 | - Action: 278 | - 's3:GetBucketAcl' 279 | Effect: Allow 280 | Resource: 281 | - !Sub ${LBAccessLogBucket.Arn} 282 | Principal: 283 | Service: delivery.logs.amazonaws.com 284 | LogGroup: 285 | Type: AWS::Logs::LogGroup 286 | Properties: 287 | LogGroupName: !Sub /ecs/omero/${AWS::StackName} 288 | 289 | MountTarget: 290 | Type: AWS::EFS::MountTarget 291 | Properties: 292 | FileSystemId: !Ref EFSFileSystem 293 | SubnetId: !Ref PrivateSubnet1Id 294 | SecurityGroups: 295 | - !Ref EFSSecurityGroup 296 | NFSAccessPoint: 297 | Type: AWS::EFS::AccessPoint 298 | Properties: 299 | FileSystemId: !Ref EFSFileSystem 300 | PosixUser: 301 | Gid: "0" 302 | Uid: "0" 303 | RootDirectory: 304 | Path: "/" 305 | 306 | OmeroserverService: 307 | Type: AWS::ECS::Service 308 | DependsOn: 309 | - OMERONetworkLoadBalancer 310 | - OmeroserverTaskDefinition 311 | - OmeroserverTCP4064Listener 312 | - OmeroserverTCP4063Listener 313 | Properties: 314 | Cluster: !Ref 'OMEROECSCluster' 315 | DeploymentConfiguration: 316 | MaximumPercent: 200 317 | MinimumHealthyPercent: 100 318 | DeploymentController: 319 | Type: ECS 320 | DesiredCount: 1 321 | LaunchType: !If 322 | - runContainerOnEC2 323 | - 'EC2' 324 | - 'FARGATE' 325 | LoadBalancers: 326 | - ContainerName: omeroserver 327 | ContainerPort: 4064 328 | TargetGroupArn: !Ref 'OmeroserverTCP4064TargetGroup' 329 | - ContainerName: omeroserver 330 | ContainerPort: 4063 331 | TargetGroupArn: !Ref 'OmeroserverTCP4063TargetGroup' 332 | EnableExecuteCommand: true 333 | NetworkConfiguration: 334 | AwsvpcConfiguration: 335 | AssignPublicIp: DISABLED 336 | SecurityGroups: 337 | - !Ref OmeroSecurityGroup 338 | Subnets: 339 | - !Ref 'PrivateSubnet1Id' 340 | PropagateTags: SERVICE 341 | SchedulingStrategy: REPLICA 342 | ServiceRegistries: 343 | - RegistryArn: !GetAtt 'OmeroserverServiceDiscoveryEntry.Arn' 344 | Tags: 345 | - Key: project 346 | Value: omero-on-aws 347 | - Key: service 348 | Value: omeroserver 349 | TaskDefinition: !Ref 'OmeroserverTaskDefinition' 350 | OmeroserverTCP4064Listener: 351 | Type: AWS::ElasticLoadBalancingV2::Listener 352 | Properties: 353 | DefaultActions: 354 | - ForwardConfig: 355 | TargetGroups: 356 | - TargetGroupArn: !Ref OmeroserverTCP4064TargetGroup 357 | Type: forward 358 | LoadBalancerArn: !Ref OMERONetworkLoadBalancer 359 | Port: 4064 360 | Protocol: TCP 361 | OmeroserverTCP4064TargetGroup: 362 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 363 | DependsOn: 364 | - OMERONetworkLoadBalancer 365 | Properties: 366 | Port: 4064 367 | Protocol: TCP 368 | TargetType: ip 369 | VpcId: !Ref VPCID 370 | Tags: 371 | - Key: project 372 | Value: omero-on-aws 373 | OmeroserverTCP4063Listener: 374 | Type: AWS::ElasticLoadBalancingV2::Listener 375 | Properties: 376 | DefaultActions: 377 | - ForwardConfig: 378 | TargetGroups: 379 | - TargetGroupArn: !Ref OmeroserverTCP4063TargetGroup 380 | Type: forward 381 | LoadBalancerArn: !Ref OMERONetworkLoadBalancer 382 | Port: 4063 383 | Protocol: TCP 384 | OmeroserverTCP4063TargetGroup: 385 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 386 | DependsOn: 387 | - OMERONetworkLoadBalancer 388 | Properties: 389 | Port: 4063 390 | Protocol: TCP 391 | TargetType: ip 392 | VpcId: !Ref VPCID 393 | Tags: 394 | - Key: project 395 | Value: omero-on-aws 396 | OmeroserverTaskDefinition: 397 | Type: AWS::ECS::TaskDefinition 398 | Properties: 399 | ContainerDefinitions: 400 | - Environment: 401 | - Name: CONFIG_omero_db_host 402 | Value: !Ref RDSEndpointAddress 403 | - Name: CONFIG_omero_db_user 404 | Value: !Ref DBUser 405 | - Name: CONFIG_omero_db_pass 406 | Value: !Join ['', ['{{resolve:secretsmanager:', !Ref RDSDatabaseSecret, ':SecretString:password}}' ]] 407 | - Name: CONFIG_omero_db_name 408 | Value: omero 409 | - Name: LOCALDOMAIN 410 | Value: !Join 411 | - '' 412 | - - !Ref 'AWS::Region' 413 | - .compute.internal 414 | - 'omero.local' 415 | - Name: ROOTPASS 416 | Value: omero 417 | Essential: true 418 | Image: !Ref OMEROServerContainerImage 419 | LinuxParameters: { initProcessEnabled: true } 420 | LogConfiguration: 421 | LogDriver: awslogs 422 | Options: 423 | awslogs-group: !Ref 'LogGroup' 424 | awslogs-region: !Ref 'AWS::Region' 425 | awslogs-stream-prefix: omeroserver 426 | Name: omeroserver 427 | MountPoints: 428 | - ContainerPath: /OMERO 429 | SourceVolume: my-efs 430 | PortMappings: 431 | - ContainerPort: 4063 432 | HostPort: 4063 433 | Protocol: tcp 434 | - ContainerPort: 4064 435 | HostPort: 4064 436 | Protocol: tcp 437 | Volumes: 438 | - name: my-efs 439 | EFSVolumeConfiguration: 440 | FilesystemId: !Ref EFSFileSystem 441 | TransitEncryption: ENABLED 442 | AuthorizationConfig: 443 | AccessPointId: !Ref NFSAccessPoint 444 | IAM: ENABLED 445 | Cpu: !Ref OMEROServerContainerCPU 446 | Memory: !Ref OMEROServerContainerMemory 447 | ExecutionRoleArn: !Ref 'OmeroserverTaskExecutionRole' 448 | TaskRoleArn: !Ref 'OmeroserverTaskRole' 449 | Family: omero-server 450 | NetworkMode: awsvpc 451 | RequiresCompatibilities: 452 | - !If 453 | - runContainerOnEC2 454 | - 'EC2' 455 | - 'FARGATE' 456 | OmeroserverTaskExecutionRole: 457 | Type: AWS::IAM::Role 458 | Properties: 459 | AssumeRolePolicyDocument: 460 | Statement: 461 | - Action: 462 | - sts:AssumeRole 463 | Effect: Allow 464 | Principal: 465 | Service: ecs-tasks.amazonaws.com 466 | Version: '2012-10-17' 467 | ManagedPolicyArns: 468 | - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy 469 | - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 470 | Tags: 471 | - Key: project 472 | Value: omero-on-aws 473 | - Key: service 474 | Value: omeroserver 475 | OmeroserverTaskRole: 476 | Type: AWS::IAM::Role 477 | Properties: 478 | AssumeRolePolicyDocument: 479 | Statement: 480 | - Action: 481 | - sts:AssumeRole 482 | Effect: Allow 483 | Principal: 484 | Service: ecs-tasks.amazonaws.com 485 | Version: '2012-10-17' 486 | Policies: 487 | - PolicyName: OmeroserverOmeroVolumeMountPolicy 488 | PolicyDocument: 489 | Statement: 490 | - Action: 491 | - elasticfilesystem:ClientMount 492 | - elasticfilesystem:ClientWrite 493 | - elasticfilesystem:ClientRootAccess 494 | Condition: 495 | StringEquals: 496 | elasticfilesystem:AccessPointArn: !Ref NFSAccessPoint 497 | Effect: Allow 498 | Principal: {} 499 | Resource: 500 | - !Join 501 | - '' 502 | - - 'arn:aws:elasticfilesystem:' 503 | - !Ref 'AWS::Region' 504 | - ':' 505 | - !Ref 'AWS::AccountId' 506 | - ':file-system/' 507 | - !Ref EFSFileSystem 508 | - PolicyName: OmeroserverSSMPolicy 509 | PolicyDocument: 510 | Statement: 511 | - Action: 512 | - ssmmessages:CreateControlChannel 513 | - ssmmessages:CreateDataChannel 514 | - ssmmessages:OpenControlChannel 515 | - ssmmessages:OpenDataChannel 516 | Effect: Allow 517 | Resource: "*" 518 | Tags: 519 | - Key: project 520 | Value: omero-on-aws 521 | - Key: service 522 | Value: omeroserver 523 | ECSAutoScalingGroup: 524 | Type: AWS::AutoScaling::AutoScalingGroup 525 | Condition: runContainerOnEC2 526 | DependsOn: 527 | - MountTarget 528 | Properties: 529 | VPCZoneIdentifier: 530 | - !Ref PrivateSubnet1Id 531 | LaunchConfigurationName: !Ref 'ContainerInstances' 532 | MinSize: '1' 533 | MaxSize: '4' 534 | DesiredCapacity: !Ref NumberofEC2Instances 535 | CreationPolicy: 536 | ResourceSignal: 537 | Timeout: PT15M 538 | UpdatePolicy: 539 | AutoScalingReplacingUpdate: 540 | WillReplace: 'true' 541 | ContainerInstances: 542 | Type: AWS::AutoScaling::LaunchConfiguration 543 | Condition: runContainerOnEC2 544 | Properties: 545 | ImageId: !Ref LatestAmiId 546 | SecurityGroups: 547 | - !Ref OmeroSecurityGroup 548 | InstanceType: !Ref 'InstanceType' 549 | IamInstanceProfile: !Ref 'EC2InstanceProfile' 550 | KeyName: !If 551 | - runContainerOnEC2 552 | - !Ref 'KeyName' 553 | - !Ref 'AWS::NoValue' 554 | UserData: 555 | Fn::Base64: !Sub | 556 | #!/bin/bash -xe 557 | echo ECS_CLUSTER=${OMEROECSCluster} >> /etc/ecs/ecs.config 558 | yum install -y aws-cfn-bootstrap bzip2 unzip 559 | /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ECSAutoScalingGroup --region ${AWS::Region} 560 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 561 | unzip awscliv2.zip 562 | ./aws/install 563 | yum install java-11-amazon-corretto-headless -y 564 | curl -LO https://anaconda.org/anaconda-adam/adam-installer/4.4.0/download/adam-installer-4.4.0-Linux-x86_64.sh 565 | bash adam-installer-4.4.0-Linux-x86_64.sh -b -p /opt/adam 566 | echo -e '\n# Anaconda Adam\nexport PATH=/opt/adam/bin:$PATH' >> /etc/bashrc 567 | source /etc/bashrc 568 | conda install -c anaconda libstdcxx-ng -y 569 | conda install -c anaconda libgcc-ng -y 570 | EC2Role: 571 | Type: AWS::IAM::Role 572 | Condition: runContainerOnEC2 573 | Properties: 574 | AssumeRolePolicyDocument: 575 | Statement: 576 | - Effect: Allow 577 | Principal: 578 | Service: 579 | - ec2.amazonaws.com 580 | Action: 581 | - sts:AssumeRole 582 | Path: / 583 | ManagedPolicyArns: 584 | - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role 585 | - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 586 | - arn:aws:iam::aws:policy/AmazonS3FullAccess 587 | Tags: 588 | - Key: project 589 | Value: omero-on-aws 590 | - Key: service 591 | Value: omeroserver 592 | EC2InstanceProfile: 593 | Type: AWS::IAM::InstanceProfile 594 | Condition: runContainerOnEC2 595 | Properties: 596 | Path: / 597 | Roles: [!Ref 'EC2Role'] 598 | 599 | OmerowebService: 600 | Type: AWS::ECS::Service 601 | DependsOn: 602 | - OMEROLoadBalancer 603 | - OmerowebHTTPSListener 604 | - OmerowebHTTPListener 605 | Properties: 606 | Cluster: !Ref 'OMEROECSCluster' 607 | DeploymentConfiguration: 608 | MaximumPercent: 200 609 | MinimumHealthyPercent: 100 610 | DeploymentController: 611 | Type: ECS 612 | DesiredCount: !Ref NumberofWebInstances 613 | LaunchType: 'FARGATE' 614 | EnableExecuteCommand: true 615 | LoadBalancers: 616 | - ContainerName: omeroweb 617 | ContainerPort: 4080 618 | TargetGroupArn: !Ref 'OmerowebTCP4080TargetGroup' 619 | NetworkConfiguration: 620 | AwsvpcConfiguration: 621 | AssignPublicIp: DISABLED 622 | SecurityGroups: 623 | - !Ref OmeroSecurityGroup 624 | Subnets: 625 | - !Ref 'PrivateSubnet1Id' 626 | - !Ref 'PrivateSubnet2Id' 627 | PropagateTags: SERVICE 628 | SchedulingStrategy: REPLICA 629 | ServiceRegistries: 630 | - RegistryArn: !GetAtt 'OmerowebServiceDiscoveryEntry.Arn' 631 | Tags: 632 | - Key: project 633 | Value: omero-on-aws 634 | - Key: service 635 | Value: omeroweb 636 | TaskDefinition: !Ref 'OmerowebTaskDefinition' 637 | 638 | HostedZoneRecord: 639 | DependsOn: 640 | - LoadBalancerSSLCert 641 | Type: AWS::Route53::RecordSet 642 | Properties: 643 | HostedZoneId: !Ref ExistingHostedZoneId 644 | Type: A 645 | Name: !Ref FullDomainName 646 | AliasTarget: 647 | DNSName: !GetAtt 'OMEROLoadBalancer.DNSName' 648 | HostedZoneId: !GetAtt 'OMEROLoadBalancer.CanonicalHostedZoneID' 649 | 650 | LoadBalancerSSLCert: 651 | Type: AWS::CertificateManager::Certificate 652 | Properties: 653 | DomainName: !Ref FullDomainName 654 | DomainValidationOptions: 655 | - DomainName: !Ref FullDomainName 656 | HostedZoneId: !Ref ExistingHostedZoneId 657 | ValidationMethod: DNS 658 | CertificateTransparencyLoggingPreference: ENABLED 659 | 660 | OmerowebHTTPSListener: 661 | Type: AWS::ElasticLoadBalancingV2::Listener 662 | Properties: 663 | Certificates: 664 | - CertificateArn: !Ref LoadBalancerSSLCert 665 | DefaultActions: 666 | - Type: forward 667 | TargetGroupArn: !Ref 'OmerowebTCP4080TargetGroup' 668 | LoadBalancerArn: !Ref 'OMEROLoadBalancer' 669 | Port: 443 670 | Protocol: HTTPS 671 | OmerowebHTTPListener: 672 | Type: AWS::ElasticLoadBalancingV2::Listener 673 | Properties: 674 | DefaultActions: 675 | - Type: redirect 676 | RedirectConfig: 677 | Protocol: HTTPS 678 | Port: '443' 679 | Host: '#{host}' 680 | Path: /#{path} 681 | Query: '#{query}' 682 | StatusCode: HTTP_301 683 | LoadBalancerArn: !Ref 'OMEROLoadBalancer' 684 | Port: 80 685 | Protocol: HTTP 686 | OmerowebTCP4080TargetGroup: 687 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 688 | Properties: 689 | Port: 4080 690 | Protocol: HTTP 691 | TargetType: ip 692 | VpcId: !Ref VPCID 693 | HealthCheckEnabled: true 694 | HealthCheckProtocol: HTTP 695 | HealthCheckPort: 4080 696 | HealthCheckPath: /index/ 697 | Matcher: 698 | HttpCode: 200-302 699 | TargetGroupAttributes: 700 | - Key: stickiness.enabled 701 | Value: true 702 | - Key: stickiness.type 703 | Value: lb_cookie 704 | - Key: stickiness.lb_cookie.duration_seconds 705 | Value: 86500 706 | Tags: 707 | - Key: project 708 | Value: omero-on-aws 709 | OmerowebTaskDefinition: 710 | Type: AWS::ECS::TaskDefinition 711 | Properties: 712 | ContainerDefinitions: 713 | - Environment: 714 | - Name: OMEROHOST 715 | Value: !Sub omeroserver.${AWS::StackName}.ecscloudmap.org 716 | - Name: LOCALDOMAIN 717 | Value: !Join 718 | - '' 719 | - - !Ref 'AWS::Region' 720 | - .compute.internal 721 | - 'omero.local' 722 | Essential: true 723 | Image: !Ref OMEROWebContainerImage 724 | LinuxParameters: { initProcessEnabled: true } 725 | LogConfiguration: 726 | LogDriver: awslogs 727 | Options: 728 | awslogs-group: !Ref 'LogGroup' 729 | awslogs-region: !Ref 'AWS::Region' 730 | awslogs-stream-prefix: omeroweb 731 | Name: omeroweb 732 | PortMappings: 733 | - ContainerPort: 4080 734 | HostPort: 4080 735 | Protocol: tcp 736 | Cpu: !Ref OMEROWebContainerCPU 737 | Memory: !Ref OMEROWebContainerMemory 738 | ExecutionRoleArn: !Ref 'OmerowebTaskExecutionRole' 739 | TaskRoleArn: !Ref 'OmerowebTaskRole' 740 | Family: omero-web 741 | NetworkMode: awsvpc 742 | RequiresCompatibilities: 743 | - 'FARGATE' 744 | OmerowebTaskExecutionRole: 745 | Type: AWS::IAM::Role 746 | Properties: 747 | AssumeRolePolicyDocument: 748 | Statement: 749 | - Action: 750 | - sts:AssumeRole 751 | Effect: Allow 752 | Principal: 753 | Service: ecs-tasks.amazonaws.com 754 | Version: '2012-10-17' 755 | ManagedPolicyArns: 756 | - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy 757 | - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 758 | Tags: 759 | - Key: project 760 | Value: omero-on-aws 761 | - Key: service 762 | Value: omeroweb 763 | OmerowebTaskRole: 764 | Type: AWS::IAM::Role 765 | Properties: 766 | AssumeRolePolicyDocument: 767 | Statement: 768 | - Action: 769 | - sts:AssumeRole 770 | Effect: Allow 771 | Principal: 772 | Service: ecs-tasks.amazonaws.com 773 | Version: '2012-10-17' 774 | Policies: 775 | - PolicyName: OmerowebSSMPolicy 776 | PolicyDocument: 777 | Statement: 778 | - Action: 779 | - ssmmessages:CreateControlChannel 780 | - ssmmessages:CreateDataChannel 781 | - ssmmessages:OpenControlChannel 782 | - ssmmessages:OpenDataChannel 783 | Effect: Allow 784 | Resource: "*" 785 | 786 | Outputs: 787 | OMEROLoadBalancerHTTPEnpoint: 788 | Description: The HTTP endpoint of the OMEROLoadBalancer 789 | Value: !Join 790 | - '' 791 | - - 'https://' 792 | - !GetAtt OMEROLoadBalancer.DNSName 793 | OMERONetworkLoadBalancerHTTPEnpoint4063: 794 | Description: The HTTP endpoint of the OMERONetworkLoadBalancer 795 | Value: !Join 796 | - '' 797 | - - 'http://' 798 | - !GetAtt OMERONetworkLoadBalancer.DNSName 799 | - ':4063' 800 | OMERONetworkLoadBalancerHTTPEnpoint4064: 801 | Description: The HTTP endpoint of the OMERONetworkLoadBalancer 802 | Value: !Join 803 | - '' 804 | - - 'http://' 805 | - !GetAtt OMERONetworkLoadBalancer.DNSName 806 | - ':4064' 807 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMEROonECS_ALBNLBwithTLS_RW_StorageGateway.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | 3 | Parameters: 4 | Namespace: 5 | Description: A string of 4-20 lowercase letters and digits, starting with a letter. Included in resource names, allowing multiple deployments. 6 | Default: monai 7 | Type: String 8 | AllowedPattern: "^[a-z]{1}[a-z0-9]{3,19}$" 9 | ConstraintDescription: Between 4-20 letters and digits, starting with a letter 10 | VPCID: 11 | Description: ID of the VPC 12 | Type: AWS::EC2::VPC::Id 13 | PublicSubnet1Id: 14 | Description: SubnetId, for Availability Zone 1 in the region in your VPC. The only one OMERO Server instance is deployed in this subnet. 15 | Type: AWS::EC2::Subnet::Id 16 | PublicSubnet2Id: 17 | Description: SubnetId, for Availability Zone 2 in the region in your VPC. None of OMERO Server instance is deployed in this subnet. 18 | Type: AWS::EC2::Subnet::Id 19 | PrivateSubnet1Id: 20 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 21 | Type: AWS::EC2::Subnet::Id 22 | PrivateSubnet2Id: 23 | Description: SubnetId, for Availability Zone 2 in the region in your VPC 24 | Type: AWS::EC2::Subnet::Id 25 | LBSecurityGroup: 26 | Description: Security group for Application Load Balancer 27 | Type: AWS::EC2::SecurityGroup::Id 28 | OmeroSecurityGroup: 29 | Description: Security group for OMERO web and service containers 30 | Type: AWS::EC2::SecurityGroup::Id 31 | EFSSecurityGroup: 32 | Description: Security group for EFS 33 | Type: AWS::EC2::SecurityGroup::Id 34 | EFSFileSystem: 35 | Description: The ID of the EFS volume 36 | Type: String 37 | LBAccessLogBucketName: 38 | Type: String 39 | Default: lb-accesslog 40 | RDSEndpointAddress: 41 | Type: String 42 | Description: The RDS database endpoinst address 43 | NumberofWebInstances: 44 | Type: Number 45 | Default: 2 46 | OMEROWebContainerCPU: 47 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 48 | Type: Number 49 | Default: 2048 50 | AllowedValues: [256, 512, 1024, 2048, 4096] 51 | OMEROWebContainerMemory: 52 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 53 | Type: Number 54 | Default: 4096 55 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 56 | OMEROServerContainerImage: 57 | Type: String 58 | Default: openmicroscopy/omero-server:latest 59 | OMEROWebContainerImage: 60 | Type: String 61 | Default: openmicroscopy/omero-web-standalone:latest 62 | LatestAmiId: 63 | Type: 'AWS::SSM::Parameter::Value' 64 | Default: '/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id' 65 | KeyName: 66 | Type: String 67 | Description: Name of an existing EC2 KeyPair to enable SSH access to the EC2 instances. OPTIONAL only for EC2 launch type. 68 | InstanceType: 69 | Description: EC2 instance type. OPTIONAL only for EC2 launch type. 70 | Type: String 71 | Default: c5.xlarge 72 | AllowedValues: [t2.large, m3.large, 73 | m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, 74 | c5.large, c5.xlarge, c5.2xlarge, c5.4xlarge, c5.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, 75 | r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] 76 | ConstraintDescription: Please choose a valid instance type. 77 | NumberofEC2Instances: 78 | Description: Number of EC2 instance to run container in ECS cluster. OPTIONAL only for EC2 lanuch type. 79 | Type: Number 80 | Default: 1 81 | OMEROServerContainerCPU: 82 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 83 | Type: Number 84 | Default: 2048 85 | AllowedValues: [256, 512, 1024, 2048, 4096] 86 | OMEROServerContainerMemory: 87 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 88 | Type: Number 89 | Default: 4096 90 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384] 91 | S3FileGatewayIp: 92 | Type: String 93 | Description: The public IP address of the EC2 instance for S3 file gateway 94 | S3BucketName: 95 | Type: String 96 | Description: The S3 bucket name for s3 file gateway 97 | MountPoint: 98 | Type: String 99 | Default: S3FileGateway 100 | DBUser: 101 | Type: String 102 | Default: omero 103 | Description: OMERO Database User 104 | NoEcho: true 105 | RDSDatabaseSecret: 106 | Type: String 107 | Description: OMERO Database Password 108 | Default: RDSDatabaseSecret 109 | ExistingHostedZoneId: 110 | Description: Existing HostedZone for Registered Domain used for ACM Certificate 111 | Type: AWS::Route53::HostedZone::Id 112 | FullDomainName: 113 | Description: Enter the Fully Qualified Domain Nanme for ACM Certificate 114 | Type: String 115 | 116 | Mappings: 117 | RegionELBAccountIdMap: 118 | us-east-1: 119 | AccountId: '127311923021' 120 | us-west-1: 121 | AccountId: '027434742980' 122 | us-west-2: 123 | AccountId: '797873946194' 124 | eu-west-1: 125 | AccountId: '156460612806' 126 | ap-northeast-1: 127 | AccountId: '582318560864' 128 | ap-northeast-2: 129 | AccountId: '600734575887' 130 | ap-southeast-1: 131 | AccountId: '114774131450' 132 | ap-southeast-2: 133 | AccountId: '783225319266' 134 | ap-south-1: 135 | AccountId: '718504428378' 136 | us-east-2: 137 | AccountId: '033677994240' 138 | sa-east-1: 139 | AccountId: '507241528517' 140 | cn-north-1: 141 | AccountId: '638102146993' 142 | eu-central-1: 143 | AccountId: '054676820928' 144 | 145 | Resources: 146 | CloudMap: 147 | Type: AWS::ServiceDiscovery::PrivateDnsNamespace 148 | Properties: 149 | Description: Service Map for OMERO ECS deployment 150 | Name: !Sub ${AWS::StackName}.ecscloudmap.org 151 | Vpc: !Ref VPCID 152 | OmerowebServiceDiscoveryEntry: 153 | Type: AWS::ServiceDiscovery::Service 154 | Properties: 155 | Description: '"omeroweb" service discovery entry in Cloud Map' 156 | DnsConfig: 157 | DnsRecords: 158 | - TTL: 60 159 | Type: A 160 | RoutingPolicy: MULTIVALUE 161 | HealthCheckCustomConfig: 162 | FailureThreshold: 1 163 | Name: omeroweb 164 | NamespaceId: !Ref 'CloudMap' 165 | OmeroserverServiceDiscoveryEntry: 166 | Type: AWS::ServiceDiscovery::Service 167 | Properties: 168 | Description: '"omeroserver" service discovery entry in Cloud Map' 169 | DnsConfig: 170 | DnsRecords: 171 | - TTL: 60 172 | Type: A 173 | RoutingPolicy: MULTIVALUE 174 | HealthCheckCustomConfig: 175 | FailureThreshold: 1 176 | Name: omeroserver 177 | NamespaceId: !Ref 'CloudMap' 178 | 179 | OMEROECSCluster: 180 | Type: AWS::ECS::Cluster 181 | Properties: 182 | ClusterName: !Sub ${AWS::StackName}-OMEROECSCluster 183 | ClusterSettings: 184 | - Name: containerInsights 185 | Value: enabled 186 | Tags: 187 | - Key: project 188 | Value: omero-on-aws 189 | OMEROLoadBalancer: 190 | DependsOn: 191 | - LBAccessLogBucket 192 | - LBAccessLogBucketPolicy 193 | Type: AWS::ElasticLoadBalancingV2::LoadBalancer 194 | Properties: 195 | LoadBalancerAttributes: 196 | - Key: load_balancing.cross_zone.enabled 197 | Value: "true" 198 | Scheme: internet-facing 199 | Subnets: 200 | - !Ref 'PublicSubnet1Id' 201 | - !Ref 'PublicSubnet2Id' 202 | SecurityGroups: 203 | - !Ref LBSecurityGroup 204 | Tags: 205 | - Key: project 206 | Value: omero-on-aws 207 | Type: application 208 | LoadBalancerAttributes: 209 | - Key: access_logs.s3.enabled 210 | Value: true 211 | - Key: access_logs.s3.bucket 212 | Value: !Join 213 | - '-' 214 | - - !Ref LBAccessLogBucketName 215 | - !Ref Namespace 216 | - !Ref AWS::AccountId 217 | OMERONetworkLoadBalancer: 218 | DependsOn: 219 | - LBAccessLogBucket 220 | - LBAccessLogBucketPolicy 221 | Type: AWS::ElasticLoadBalancingV2::LoadBalancer 222 | Properties: 223 | Scheme: internet-facing 224 | Subnets: 225 | - !Ref 'PublicSubnet1Id' 226 | - !Ref 'PublicSubnet2Id' 227 | Tags: 228 | - Key: project 229 | Value: omero-on-aws 230 | Type: network 231 | LoadBalancerAttributes: 232 | - Key: access_logs.s3.enabled 233 | Value: true 234 | - Key: access_logs.s3.bucket 235 | Value: !Join 236 | - '-' 237 | - - !Ref LBAccessLogBucketName 238 | - !Ref Namespace 239 | - !Ref AWS::AccountId 240 | LBAccessLogBucket: 241 | Type: AWS::S3::Bucket 242 | Properties: 243 | BucketName: !Join 244 | - '-' 245 | - - !Ref LBAccessLogBucketName 246 | - !Ref Namespace 247 | - !Ref AWS::AccountId 248 | BucketEncryption: 249 | ServerSideEncryptionConfiguration: 250 | - ServerSideEncryptionByDefault: 251 | SSEAlgorithm: AES256 252 | VersioningConfiguration: 253 | Status: Enabled 254 | LBAccessLogBucketPolicy: 255 | Type: AWS::S3::BucketPolicy 256 | Properties: 257 | Bucket: !Ref LBAccessLogBucket 258 | PolicyDocument: 259 | Statement: 260 | - Action: 261 | - 's3:PutObject' 262 | Effect: Allow 263 | Resource: 264 | - !Sub '${LBAccessLogBucket.Arn}/*' 265 | Principal: 266 | AWS: !FindInMap [RegionELBAccountIdMap, !Ref 'AWS::Region', AccountId] 267 | - Action: 268 | - 's3:PutObject' 269 | Effect: Allow 270 | Resource: 271 | - !Sub '${LBAccessLogBucket.Arn}/*' 272 | Principal: 273 | Service: delivery.logs.amazonaws.com 274 | Condition: 275 | StringEquals: 276 | s3:x-amz-acl: bucket-owner-full-control 277 | - Action: 278 | - 's3:GetBucketAcl' 279 | Effect: Allow 280 | Resource: 281 | - !Sub ${LBAccessLogBucket.Arn} 282 | Principal: 283 | Service: delivery.logs.amazonaws.com 284 | LogGroup: 285 | Type: AWS::Logs::LogGroup 286 | Properties: 287 | LogGroupName: !Sub /ecs/omero/${AWS::StackName} 288 | 289 | MountTarget: 290 | Type: AWS::EFS::MountTarget 291 | Properties: 292 | FileSystemId: !Ref EFSFileSystem 293 | SubnetId: !Ref PrivateSubnet1Id 294 | SecurityGroups: 295 | - !Ref EFSSecurityGroup 296 | NFSAccessPoint: 297 | Type: AWS::EFS::AccessPoint 298 | Properties: 299 | FileSystemId: !Ref EFSFileSystem 300 | PosixUser: 301 | Gid: "0" 302 | Uid: "0" 303 | RootDirectory: 304 | Path: "/" 305 | 306 | OmeroserverService: 307 | Type: AWS::ECS::Service 308 | DependsOn: 309 | - OMERONetworkLoadBalancer 310 | - OmeroserverTaskDefinition 311 | - OmeroserverTCP4064Listener 312 | - OmeroserverTCP4063Listener 313 | Properties: 314 | Cluster: !Ref 'OMEROECSCluster' 315 | DeploymentConfiguration: 316 | MaximumPercent: 200 317 | MinimumHealthyPercent: 100 318 | DeploymentController: 319 | Type: ECS 320 | DesiredCount: 1 321 | LaunchType: 'EC2' 322 | LoadBalancers: 323 | - ContainerName: omeroserver 324 | ContainerPort: 4064 325 | TargetGroupArn: !Ref 'OmeroserverTCP4064TargetGroup' 326 | - ContainerName: omeroserver 327 | ContainerPort: 4063 328 | TargetGroupArn: !Ref 'OmeroserverTCP4063TargetGroup' 329 | EnableExecuteCommand: true 330 | NetworkConfiguration: 331 | AwsvpcConfiguration: 332 | AssignPublicIp: DISABLED 333 | SecurityGroups: 334 | - !Ref OmeroSecurityGroup 335 | Subnets: 336 | - !Ref 'PrivateSubnet1Id' 337 | PropagateTags: SERVICE 338 | SchedulingStrategy: REPLICA 339 | ServiceRegistries: 340 | - RegistryArn: !GetAtt 'OmeroserverServiceDiscoveryEntry.Arn' 341 | Tags: 342 | - Key: project 343 | Value: omero-on-aws 344 | - Key: service 345 | Value: omeroserver 346 | TaskDefinition: !Ref 'OmeroserverTaskDefinition' 347 | OmeroserverTCP4064Listener: 348 | Type: AWS::ElasticLoadBalancingV2::Listener 349 | Properties: 350 | DefaultActions: 351 | - ForwardConfig: 352 | TargetGroups: 353 | - TargetGroupArn: !Ref OmeroserverTCP4064TargetGroup 354 | Type: forward 355 | LoadBalancerArn: !Ref OMERONetworkLoadBalancer 356 | Port: 4064 357 | Protocol: TCP 358 | OmeroserverTCP4064TargetGroup: 359 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 360 | DependsOn: 361 | - OMERONetworkLoadBalancer 362 | Properties: 363 | Port: 4064 364 | Protocol: TCP 365 | TargetType: ip 366 | VpcId: !Ref VPCID 367 | Tags: 368 | - Key: project 369 | Value: omero-on-aws 370 | OmeroserverTCP4063Listener: 371 | Type: AWS::ElasticLoadBalancingV2::Listener 372 | Properties: 373 | DefaultActions: 374 | - ForwardConfig: 375 | TargetGroups: 376 | - TargetGroupArn: !Ref OmeroserverTCP4063TargetGroup 377 | Type: forward 378 | LoadBalancerArn: !Ref OMERONetworkLoadBalancer 379 | Port: 4063 380 | Protocol: TCP 381 | OmeroserverTCP4063TargetGroup: 382 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 383 | DependsOn: 384 | - OMERONetworkLoadBalancer 385 | Properties: 386 | Port: 4063 387 | Protocol: TCP 388 | TargetType: ip 389 | VpcId: !Ref VPCID 390 | Tags: 391 | - Key: project 392 | Value: omero-on-aws 393 | OmeroserverTaskDefinition: 394 | Type: AWS::ECS::TaskDefinition 395 | Properties: 396 | ContainerDefinitions: 397 | - Environment: 398 | - Name: CONFIG_omero_db_host 399 | Value: !GetAtt 'RDSInstance.Endpoint.Address' 400 | - Name: CONFIG_omero_db_user 401 | Value: !Ref DBUser 402 | - Name: CONFIG_omero_db_pass 403 | Value: !Join ['', ['{{resolve:secretsmanager:', !Ref RDSDatabaseSecret, ':SecretString:password}}' ]] 404 | - Name: CONFIG_omero_db_name 405 | Value: omero 406 | - Name: LOCALDOMAIN 407 | Value: !Join 408 | - '' 409 | - - !Ref 'AWS::Region' 410 | - .compute.internal 411 | - 'omero.local' 412 | - Name: ROOTPASS 413 | Value: omero 414 | Essential: true 415 | Image: !Ref OMEROServerContainerImage 416 | LinuxParameters: { InitProcessEnabled: true } 417 | LogConfiguration: 418 | LogDriver: awslogs 419 | Options: 420 | awslogs-group: !Ref 'LogGroup' 421 | awslogs-region: !Ref 'AWS::Region' 422 | awslogs-stream-prefix: omeroserver 423 | Name: omeroserver 424 | MountPoints: 425 | - ContainerPath: /OMERO 426 | SourceVolume: my-fg 427 | PortMappings: 428 | - ContainerPort: 4063 429 | HostPort: 4063 430 | Protocol: tcp 431 | - ContainerPort: 4064 432 | HostPort: 4064 433 | Protocol: tcp 434 | Volumes: 435 | - Name: my-fg 436 | Host: 437 | SourcePath: !Sub /${MountPoint} 438 | Cpu: !Ref OMEROServerContainerCPU 439 | Memory: !Ref OMEROServerContainerMemory 440 | ExecutionRoleArn: !Ref 'OmeroserverTaskExecutionRole' 441 | TaskRoleArn: !Ref 'OmeroserverTaskRole' 442 | Family: omero-server 443 | NetworkMode: awsvpc 444 | RequiresCompatibilities: 445 | - 'EC2' 446 | 447 | OmeroserverTaskExecutionRole: 448 | Type: AWS::IAM::Role 449 | Properties: 450 | AssumeRolePolicyDocument: 451 | Statement: 452 | - Action: 453 | - sts:AssumeRole 454 | Effect: Allow 455 | Principal: 456 | Service: ecs-tasks.amazonaws.com 457 | Version: '2012-10-17' 458 | ManagedPolicyArns: 459 | - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy 460 | - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 461 | Tags: 462 | - Key: project 463 | Value: omero-on-aws 464 | - Key: service 465 | Value: omeroserver 466 | OmeroserverTaskRole: 467 | Type: AWS::IAM::Role 468 | Properties: 469 | AssumeRolePolicyDocument: 470 | Statement: 471 | - Action: 472 | - sts:AssumeRole 473 | Effect: Allow 474 | Principal: 475 | Service: ecs-tasks.amazonaws.com 476 | Version: '2012-10-17' 477 | Policies: 478 | - PolicyName: OmeroserverOmeroVolumeMountPolicy 479 | PolicyDocument: 480 | Statement: 481 | - Action: 482 | - elasticfilesystem:ClientMount 483 | - elasticfilesystem:ClientWrite 484 | - elasticfilesystem:ClientRootAccess 485 | Condition: 486 | StringEquals: 487 | elasticfilesystem:AccessPointArn: !Ref NFSAccessPoint 488 | Effect: Allow 489 | Principal: {} 490 | Resource: 491 | - !Join 492 | - '' 493 | - - 'arn:aws:elasticfilesystem:' 494 | - !Ref 'AWS::Region' 495 | - ':' 496 | - !Ref 'AWS::AccountId' 497 | - ':file-system/' 498 | - !Ref EFSFileSystem 499 | - PolicyName: OmeroserverSSMPolicy 500 | PolicyDocument: 501 | Statement: 502 | - Action: 503 | - ssmmessages:CreateControlChannel 504 | - ssmmessages:CreateDataChannel 505 | - ssmmessages:OpenControlChannel 506 | - ssmmessages:OpenDataChannel 507 | Effect: Allow 508 | Resource: "*" 509 | Tags: 510 | - Key: project 511 | Value: omero-on-aws 512 | - Key: service 513 | Value: omeroserver 514 | ECSAutoScalingGroup: 515 | Type: AWS::AutoScaling::AutoScalingGroup 516 | DependsOn: 517 | - MountTarget 518 | Properties: 519 | VPCZoneIdentifier: 520 | - !Ref PrivateSubnet1Id 521 | LaunchConfigurationName: !Ref 'ContainerInstances' 522 | MinSize: '1' 523 | MaxSize: '4' 524 | DesiredCapacity: !Ref NumberofEC2Instances 525 | CreationPolicy: 526 | ResourceSignal: 527 | Timeout: PT15M 528 | UpdatePolicy: 529 | AutoScalingReplacingUpdate: 530 | WillReplace: 'true' 531 | ContainerInstances: 532 | Type: AWS::AutoScaling::LaunchConfiguration 533 | Metadata: 534 | AWS::CloudFormation::Init: 535 | configSets: 536 | MountConfig: 537 | - mount 538 | mount: 539 | commands: 540 | 01_newfolder: 541 | command: !Sub "mkdir /${MountPoint}" 542 | 02_mount: 543 | command: !Sub > 544 | mount -t nfs -o nolock,hard ${S3FileGatewayIp}:/${S3BucketName} /${MountPoint} 545 | 03_echo: 546 | command: !Sub > 547 | echo "${S3FileGatewayIp}:/${S3BucketName} /${MountPoint} nfs defaults,_netdev,tls 0 0" >> /etc/fstab 548 | Properties: 549 | ImageId: !Ref LatestAmiId 550 | SecurityGroups: 551 | - !Ref OmeroSecurityGroup 552 | InstanceType: !Ref 'InstanceType' 553 | IamInstanceProfile: !Ref 'EC2InstanceProfile' 554 | KeyName: !Ref 'KeyName' 555 | UserData: 556 | Fn::Base64: !Sub | 557 | #!/bin/bash -xe 558 | echo ECS_CLUSTER=${OMEROECSCluster} >> /etc/ecs/ecs.config 559 | yum install -y aws-cfn-bootstrap bzip2 unzip 560 | /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource ContainerInstances --configsets MountConfig --region ${AWS::Region} 561 | /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ECSAutoScalingGroup --region ${AWS::Region} || echo "failed to notify stack" 562 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 563 | unzip awscliv2.zip 564 | ./aws/install 565 | yum install java-11-amazon-corretto-headless -y 566 | curl -LO https://anaconda.org/anaconda-adam/adam-installer/4.4.0/download/adam-installer-4.4.0-Linux-x86_64.sh 567 | bash adam-installer-4.4.0-Linux-x86_64.sh -b -p /opt/adam 568 | echo -e '\n# Anaconda Adam\nexport PATH=/opt/adam/bin:$PATH' >> /etc/bashrc 569 | source /etc/bashrc 570 | conda install -c anaconda libstdcxx-ng -y 571 | conda install -c anaconda libgcc-ng -y 572 | EC2Role: 573 | Type: AWS::IAM::Role 574 | Properties: 575 | AssumeRolePolicyDocument: 576 | Statement: 577 | - Effect: Allow 578 | Principal: 579 | Service: 580 | - ec2.amazonaws.com 581 | Action: 582 | - sts:AssumeRole 583 | Path: / 584 | ManagedPolicyArns: 585 | - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role 586 | - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 587 | - arn:aws:iam::aws:policy/AmazonS3FullAccess 588 | Tags: 589 | - Key: project 590 | Value: omero-on-aws 591 | - Key: service 592 | Value: omeroserver 593 | EC2InstanceProfile: 594 | Type: AWS::IAM::InstanceProfile 595 | Properties: 596 | Path: / 597 | Roles: [!Ref 'EC2Role'] 598 | 599 | OmerowebService: 600 | Type: AWS::ECS::Service 601 | DependsOn: 602 | - OMEROLoadBalancer 603 | - OmerowebHTTPSListener 604 | - OmerowebHTTPListener 605 | Properties: 606 | Cluster: !Ref 'OMEROECSCluster' 607 | DeploymentConfiguration: 608 | MaximumPercent: 200 609 | MinimumHealthyPercent: 100 610 | DeploymentController: 611 | Type: ECS 612 | DesiredCount: !Ref NumberofWebInstances 613 | LaunchType: 'FARGATE' 614 | EnableExecuteCommand: true 615 | LoadBalancers: 616 | - ContainerName: omeroweb 617 | ContainerPort: 4080 618 | TargetGroupArn: !Ref 'OmerowebTCP4080TargetGroup' 619 | NetworkConfiguration: 620 | AwsvpcConfiguration: 621 | AssignPublicIp: DISABLED 622 | SecurityGroups: 623 | - !Ref OmeroSecurityGroup 624 | Subnets: 625 | - !Ref 'PrivateSubnet1Id' 626 | - !Ref 'PrivateSubnet2Id' 627 | PropagateTags: SERVICE 628 | SchedulingStrategy: REPLICA 629 | ServiceRegistries: 630 | - RegistryArn: !GetAtt 'OmerowebServiceDiscoveryEntry.Arn' 631 | Tags: 632 | - Key: project 633 | Value: omero-on-aws 634 | - Key: service 635 | Value: omeroweb 636 | TaskDefinition: !Ref 'OmerowebTaskDefinition' 637 | 638 | HostedZoneRecord: 639 | DependsOn: 640 | - LoadBalancerSSLCert 641 | Type: AWS::Route53::RecordSet 642 | Properties: 643 | HostedZoneId: !Ref ExistingHostedZoneId 644 | Type: A 645 | Name: !Ref FullDomainName 646 | AliasTarget: 647 | DNSName: !GetAtt 'OMEROLoadBalancer.DNSName' 648 | HostedZoneId: !GetAtt 'OMEROLoadBalancer.CanonicalHostedZoneID' 649 | 650 | LoadBalancerSSLCert: 651 | Type: AWS::CertificateManager::Certificate 652 | Properties: 653 | DomainName: !Ref FullDomainName 654 | DomainValidationOptions: 655 | - DomainName: !Ref FullDomainName 656 | HostedZoneId: !Ref ExistingHostedZoneId 657 | ValidationMethod: DNS 658 | CertificateTransparencyLoggingPreference: ENABLED 659 | 660 | OmerowebHTTPSListener: 661 | Type: AWS::ElasticLoadBalancingV2::Listener 662 | Properties: 663 | Certificates: 664 | - CertificateArn: !Ref LoadBalancerSSLCert 665 | DefaultActions: 666 | - Type: forward 667 | TargetGroupArn: !Ref 'OmerowebTCP4080TargetGroup' 668 | LoadBalancerArn: !Ref 'OMEROLoadBalancer' 669 | Port: 443 670 | Protocol: HTTPS 671 | OmerowebHTTPListener: 672 | Type: AWS::ElasticLoadBalancingV2::Listener 673 | Properties: 674 | DefaultActions: 675 | - Type: redirect 676 | RedirectConfig: 677 | Protocol: HTTPS 678 | Port: '443' 679 | Host: '#{host}' 680 | Path: /#{path} 681 | Query: '#{query}' 682 | StatusCode: HTTP_301 683 | LoadBalancerArn: !Ref 'OMEROLoadBalancer' 684 | Port: 80 685 | Protocol: HTTP 686 | OmerowebTCP4080TargetGroup: 687 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 688 | Properties: 689 | Port: 4080 690 | Protocol: HTTP 691 | TargetType: ip 692 | VpcId: !Ref VPCID 693 | HealthCheckEnabled: true 694 | HealthCheckProtocol: HTTP 695 | HealthCheckPort: 4080 696 | HealthCheckPath: /index/ 697 | Matcher: 698 | HttpCode: 200-302 699 | TargetGroupAttributes: 700 | - Key: stickiness.enabled 701 | Value: true 702 | - Key: stickiness.type 703 | Value: lb_cookie 704 | - Key: stickiness.lb_cookie.duration_seconds 705 | Value: 86500 706 | Tags: 707 | - Key: project 708 | Value: omero-on-aws 709 | OmerowebTaskDefinition: 710 | Type: AWS::ECS::TaskDefinition 711 | Properties: 712 | ContainerDefinitions: 713 | - Environment: 714 | - Name: OMEROHOST 715 | Value: !Sub omeroserver.${AWS::StackName}.ecscloudmap.org 716 | - Name: LOCALDOMAIN 717 | Value: !Join 718 | - '' 719 | - - !Ref 'AWS::Region' 720 | - .compute.internal 721 | - 'omero.local' 722 | Essential: true 723 | Image: !Ref OMEROWebContainerImage 724 | LinuxParameters: { InitProcessEnabled: true } 725 | LogConfiguration: 726 | LogDriver: awslogs 727 | Options: 728 | awslogs-group: !Ref 'LogGroup' 729 | awslogs-region: !Ref 'AWS::Region' 730 | awslogs-stream-prefix: omeroweb 731 | Name: omeroweb 732 | PortMappings: 733 | - ContainerPort: 4080 734 | HostPort: 4080 735 | Protocol: tcp 736 | Cpu: !Ref OMEROWebContainerCPU 737 | Memory: !Ref OMEROWebContainerMemory 738 | ExecutionRoleArn: !Ref 'OmerowebTaskExecutionRole' 739 | TaskRoleArn: !Ref 'OmerowebTaskRole' 740 | Family: omero-web 741 | NetworkMode: awsvpc 742 | RequiresCompatibilities: 743 | - 'FARGATE' 744 | OmerowebTaskExecutionRole: 745 | Type: AWS::IAM::Role 746 | Properties: 747 | AssumeRolePolicyDocument: 748 | Statement: 749 | - Action: 750 | - sts:AssumeRole 751 | Effect: Allow 752 | Principal: 753 | Service: ecs-tasks.amazonaws.com 754 | Version: '2012-10-17' 755 | ManagedPolicyArns: 756 | - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy 757 | - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 758 | Tags: 759 | - Key: project 760 | Value: omero-on-aws 761 | - Key: service 762 | Value: omeroweb 763 | OmerowebTaskRole: 764 | Type: AWS::IAM::Role 765 | Properties: 766 | AssumeRolePolicyDocument: 767 | Statement: 768 | - Action: 769 | - sts:AssumeRole 770 | Effect: Allow 771 | Principal: 772 | Service: ecs-tasks.amazonaws.com 773 | Version: '2012-10-17' 774 | Policies: 775 | - PolicyName: OmerowebSSMPolicy 776 | PolicyDocument: 777 | Statement: 778 | - Action: 779 | - ssmmessages:CreateControlChannel 780 | - ssmmessages:CreateDataChannel 781 | - ssmmessages:OpenControlChannel 782 | - ssmmessages:OpenDataChannel 783 | Effect: Allow 784 | Resource: "*" 785 | 786 | Outputs: 787 | OMEROLoadBalancerHTTPEnpoint: 788 | Description: The HTTP endpoint of the OMEROLoadBalancer 789 | Value: !Join 790 | - '' 791 | - - 'https://' 792 | - !GetAtt OMEROLoadBalancer.DNSName 793 | OMERONetworkLoadBalancerHTTPEnpoint4063: 794 | Description: The HTTP endpoint of the OMERONetworkLoadBalancer 795 | Value: !Join 796 | - '' 797 | - - 'http://' 798 | - !GetAtt OMERONetworkLoadBalancer.DNSName 799 | - ':4063' 800 | OMERONetworkLoadBalancerHTTPEnpoint4064: 801 | Description: The HTTP endpoint of the OMERONetworkLoadBalancer 802 | Value: !Join 803 | - '' 804 | - - 'http://' 805 | - !GetAtt OMERONetworkLoadBalancer.DNSName 806 | - ':4064' 807 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMEROonECS_ALBwithTLS_RW.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | 3 | Parameters: 4 | Namespace: 5 | Description: A string of 4-20 lowercase letters and digits, starting with a letter. Included in resource names, allowing multiple deployments. 6 | Default: monai 7 | Type: String 8 | AllowedPattern: "^[a-z]{1}[a-z0-9]{3,19}$" 9 | ConstraintDescription: Between 4-20 letters and digits, starting with a letter 10 | VPCID: 11 | Description: ID of the VPC 12 | Type: AWS::EC2::VPC::Id 13 | PublicSubnet1Id: 14 | Description: SubnetId, for Availability Zone 1 in the region in your VPC. The only one OMERO Server instance is deployed in this subnet. 15 | Type: AWS::EC2::Subnet::Id 16 | PublicSubnet2Id: 17 | Description: SubnetId, for Availability Zone 2 in the region in your VPC. None of OMERO Server instance is deployed in this subnet. 18 | Type: AWS::EC2::Subnet::Id 19 | PrivateSubnet1Id: 20 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 21 | Type: AWS::EC2::Subnet::Id 22 | PrivateSubnet2Id: 23 | Description: SubnetId, for Availability Zone 2 in the region in your VPC 24 | Type: AWS::EC2::Subnet::Id 25 | LBSecurityGroup: 26 | Description: Security group for Application Load Balancer 27 | Type: AWS::EC2::SecurityGroup::Id 28 | OmeroSecurityGroup: 29 | Description: Security group for OMERO web and service containers 30 | Type: AWS::EC2::SecurityGroup::Id 31 | EFSSecurityGroup: 32 | Description: Security group for EFS 33 | Type: AWS::EC2::SecurityGroup::Id 34 | EFSFileSystem: 35 | Description: The ID of the EFS volume 36 | Type: String 37 | LBAccessLogBucketName: 38 | Type: String 39 | Default: lb-accesslog 40 | RDSEndpointAddress: 41 | Type: String 42 | Description: The RDS database endpoinst address 43 | NumberofWebInstances: 44 | Type: Number 45 | Default: 2 46 | OMEROWebContainerCPU: 47 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 48 | Type: Number 49 | Default: 2048 50 | AllowedValues: [256, 512, 1024, 2048, 4096] 51 | OMEROWebContainerMemory: 52 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 53 | Type: Number 54 | Default: 4096 55 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 56 | OMEROServerContainerImage: 57 | Type: String 58 | Default: openmicroscopy/omero-server:latest 59 | OMEROWebContainerImage: 60 | Type: String 61 | Default: openmicroscopy/omero-web-standalone:latest 62 | ContainerOnEC2: 63 | Type: String 64 | Default: N 65 | Description: will the containers be hosted on ECS EC2 or Fargate launch type 66 | AllowedValues: [Y, N] 67 | LatestAmiId: 68 | Type: 'AWS::SSM::Parameter::Value' 69 | Default: '/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id' 70 | KeyName: 71 | Type: String 72 | Description: Name of an existing EC2 KeyPair to enable SSH access to the EC2 instances. OPTIONAL only for EC2 launch type. 73 | InstanceType: 74 | Description: EC2 instance type. OPTIONAL only for EC2 launch type. 75 | Type: String 76 | Default: m4.xlarge 77 | AllowedValues: [t2.large, m3.large, 78 | m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, 79 | c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge, 80 | c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, 81 | r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] 82 | ConstraintDescription: Please choose a valid instance type. 83 | NumberofEC2Instances: 84 | Description: Number of EC2 instance to run container in ECS cluster. OPTIONAL only for EC2 lanuch type. 85 | Type: Number 86 | Default: 3 87 | OMEROServerContainerCPU: 88 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 89 | Type: Number 90 | Default: 4096 91 | AllowedValues: [256, 512, 1024, 2048, 4096] 92 | OMEROServerContainerMemory: 93 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 94 | Type: Number 95 | Default: 10240 96 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 97 | DBUser: 98 | Type: String 99 | Default: omero 100 | Description: OMERO Database User 101 | NoEcho: true 102 | RDSDatabaseSecret: 103 | Type: String 104 | Description: OMERO Database Password 105 | Default: RDSDatabaseSecret 106 | ExistingHostedZoneId: 107 | Description: Existing HostedZone for Registered Domain used for ACM Certificate 108 | Type: AWS::Route53::HostedZone::Id 109 | FullDomainName: 110 | Description: Enter the Fully Qualified Domain Nanme for ACM Certificate 111 | Type: String 112 | 113 | Conditions: 114 | runContainerOnEC2: !Equals [ !Ref 'ContainerOnEC2', 'Y' ] 115 | 116 | Mappings: 117 | RegionELBAccountIdMap: 118 | us-east-1: 119 | AccountId: '127311923021' 120 | us-west-1: 121 | AccountId: '027434742980' 122 | us-west-2: 123 | AccountId: '797873946194' 124 | eu-west-1: 125 | AccountId: '156460612806' 126 | ap-northeast-1: 127 | AccountId: '582318560864' 128 | ap-northeast-2: 129 | AccountId: '600734575887' 130 | ap-southeast-1: 131 | AccountId: '114774131450' 132 | ap-southeast-2: 133 | AccountId: '783225319266' 134 | ap-south-1: 135 | AccountId: '718504428378' 136 | us-east-2: 137 | AccountId: '033677994240' 138 | sa-east-1: 139 | AccountId: '507241528517' 140 | cn-north-1: 141 | AccountId: '638102146993' 142 | eu-central-1: 143 | AccountId: '054676820928' 144 | 145 | Resources: 146 | CloudMap: 147 | Type: AWS::ServiceDiscovery::PrivateDnsNamespace 148 | Properties: 149 | Description: Service Map for OMERO ECS deployment 150 | Name: !Sub ${AWS::StackName}.ecscloudmap.org 151 | Vpc: !Ref VPCID 152 | OmerowebServiceDiscoveryEntry: 153 | Type: AWS::ServiceDiscovery::Service 154 | Properties: 155 | Description: '"omeroweb" service discovery entry in Cloud Map' 156 | DnsConfig: 157 | DnsRecords: 158 | - TTL: 60 159 | Type: A 160 | RoutingPolicy: MULTIVALUE 161 | HealthCheckCustomConfig: 162 | FailureThreshold: 1 163 | Name: omeroweb 164 | NamespaceId: !Ref 'CloudMap' 165 | OmeroserverServiceDiscoveryEntry: 166 | Type: AWS::ServiceDiscovery::Service 167 | Properties: 168 | Description: '"omeroserver" service discovery entry in Cloud Map' 169 | DnsConfig: 170 | DnsRecords: 171 | - TTL: 60 172 | Type: A 173 | RoutingPolicy: MULTIVALUE 174 | HealthCheckCustomConfig: 175 | FailureThreshold: 1 176 | Name: omeroserver 177 | NamespaceId: !Ref 'CloudMap' 178 | 179 | OMEROECSCluster: 180 | Type: AWS::ECS::Cluster 181 | Properties: 182 | ClusterName: !Sub ${AWS::StackName}-OMEROECSCluster 183 | ClusterSettings: 184 | - Name: containerInsights 185 | Value: enabled 186 | Tags: 187 | - Key: project 188 | Value: omero-on-aws 189 | OMEROLoadBalancer: 190 | DependsOn: 191 | - LBAccessLogBucket 192 | - LBAccessLogBucketPolicy 193 | Type: AWS::ElasticLoadBalancingV2::LoadBalancer 194 | Properties: 195 | LoadBalancerAttributes: 196 | - Key: load_balancing.cross_zone.enabled 197 | Value: "true" 198 | Scheme: internet-facing 199 | Subnets: 200 | - !Ref 'PublicSubnet1Id' 201 | - !Ref 'PublicSubnet2Id' 202 | SecurityGroups: 203 | - !Ref LBSecurityGroup 204 | Tags: 205 | - Key: project 206 | Value: omero-on-aws 207 | Type: application 208 | LoadBalancerAttributes: 209 | - Key: access_logs.s3.enabled 210 | Value: true 211 | - Key: access_logs.s3.bucket 212 | Value: !Join 213 | - '-' 214 | - - !Ref LBAccessLogBucketName 215 | - !Ref Namespace 216 | - !Ref AWS::AccountId 217 | LBAccessLogBucket: 218 | Type: AWS::S3::Bucket 219 | Properties: 220 | BucketName: !Join 221 | - '-' 222 | - - !Ref LBAccessLogBucketName 223 | - !Ref Namespace 224 | - !Ref AWS::AccountId 225 | BucketEncryption: 226 | ServerSideEncryptionConfiguration: 227 | - ServerSideEncryptionByDefault: 228 | SSEAlgorithm: AES256 229 | VersioningConfiguration: 230 | Status: Enabled 231 | LBAccessLogBucketPolicy: 232 | Type: AWS::S3::BucketPolicy 233 | Properties: 234 | Bucket: !Ref LBAccessLogBucket 235 | PolicyDocument: 236 | Statement: 237 | - Action: 238 | - 's3:PutObject' 239 | Effect: Allow 240 | Resource: 241 | - !Sub '${LBAccessLogBucket.Arn}/*' 242 | Principal: 243 | AWS: !FindInMap [RegionELBAccountIdMap, !Ref 'AWS::Region', AccountId] 244 | - Action: 245 | - 's3:PutObject' 246 | Effect: Allow 247 | Resource: 248 | - !Sub '${LBAccessLogBucket.Arn}/*' 249 | Principal: 250 | Service: delivery.logs.amazonaws.com 251 | Condition: 252 | StringEquals: 253 | s3:x-amz-acl: bucket-owner-full-control 254 | - Action: 255 | - 's3:GetBucketAcl' 256 | Effect: Allow 257 | Resource: 258 | - !Sub ${LBAccessLogBucket.Arn} 259 | Principal: 260 | Service: delivery.logs.amazonaws.com 261 | LogGroup: 262 | Type: AWS::Logs::LogGroup 263 | Properties: 264 | LogGroupName: !Sub /ecs/omero/${AWS::StackName} 265 | 266 | MountTarget: 267 | Type: AWS::EFS::MountTarget 268 | Properties: 269 | FileSystemId: !Ref EFSFileSystem 270 | SubnetId: !Ref PrivateSubnet1Id 271 | SecurityGroups: 272 | - !Ref EFSSecurityGroup 273 | NFSAccessPoint: 274 | Type: AWS::EFS::AccessPoint 275 | Properties: 276 | FileSystemId: !Ref EFSFileSystem 277 | PosixUser: 278 | Gid: "0" 279 | Uid: "0" 280 | RootDirectory: 281 | Path: "/" 282 | 283 | OmeroserverService: 284 | Type: AWS::ECS::Service 285 | DependsOn: 286 | - OmeroserverTaskDefinition 287 | Properties: 288 | Cluster: !Ref 'OMEROECSCluster' 289 | DeploymentConfiguration: 290 | MaximumPercent: 200 291 | MinimumHealthyPercent: 100 292 | DeploymentController: 293 | Type: ECS 294 | DesiredCount: 1 295 | LaunchType: !If 296 | - runContainerOnEC2 297 | - 'EC2' 298 | - 'FARGATE' 299 | EnableExecuteCommand: true 300 | NetworkConfiguration: 301 | AwsvpcConfiguration: 302 | AssignPublicIp: DISABLED 303 | SecurityGroups: 304 | - !Ref OmeroSecurityGroup 305 | Subnets: 306 | - !Ref 'PrivateSubnet1Id' 307 | PropagateTags: SERVICE 308 | SchedulingStrategy: REPLICA 309 | ServiceRegistries: 310 | - RegistryArn: !GetAtt 'OmeroserverServiceDiscoveryEntry.Arn' 311 | Tags: 312 | - Key: project 313 | Value: omero-on-aws 314 | - Key: service 315 | Value: omeroserver 316 | TaskDefinition: !Ref 'OmeroserverTaskDefinition' 317 | 318 | OmeroserverTaskDefinition: 319 | Type: AWS::ECS::TaskDefinition 320 | Properties: 321 | ContainerDefinitions: 322 | - Environment: 323 | - Name: CONFIG_omero_db_host 324 | Value: !Ref RDSEndpointAddress 325 | - Name: CONFIG_omero_db_user 326 | Value: !Ref DBUser 327 | - Name: CONFIG_omero_db_pass 328 | Value: !Join ['', ['{{resolve:secretsmanager:', !Ref RDSDatabaseSecret, ':SecretString:password}}' ]] 329 | - Name: CONFIG_omero_db_name 330 | Value: omero 331 | - Name: LOCALDOMAIN 332 | Value: !Join 333 | - '' 334 | - - !Ref 'AWS::Region' 335 | - .compute.internal 336 | - 'omero.local' 337 | - Name: ROOTPASS 338 | Value: omero 339 | Essential: true 340 | Image: !Ref OMEROServerContainerImage 341 | LinuxParameters: { initProcessEnabled: true } 342 | LogConfiguration: 343 | LogDriver: awslogs 344 | Options: 345 | awslogs-group: !Ref 'LogGroup' 346 | awslogs-region: !Ref 'AWS::Region' 347 | awslogs-stream-prefix: omeroserver 348 | Name: omeroserver 349 | MountPoints: 350 | - ContainerPath: /OMERO 351 | SourceVolume: my-efs 352 | PortMappings: 353 | - ContainerPort: 4063 354 | HostPort: 4063 355 | Protocol: tcp 356 | - ContainerPort: 4064 357 | HostPort: 4064 358 | Protocol: tcp 359 | Volumes: 360 | - name: my-efs 361 | EFSVolumeConfiguration: 362 | FilesystemId: !Ref EFSFileSystem 363 | TransitEncryption: ENABLED 364 | AuthorizationConfig: 365 | AccessPointId: !Ref NFSAccessPoint 366 | IAM: ENABLED 367 | Cpu: !Ref OMEROServerContainerCPU 368 | Memory: !Ref OMEROServerContainerMemory 369 | ExecutionRoleArn: !Ref 'OmeroserverTaskExecutionRole' 370 | TaskRoleArn: !Ref 'OmeroserverTaskRole' 371 | Family: omero-server 372 | NetworkMode: awsvpc 373 | RequiresCompatibilities: 374 | - !If 375 | - runContainerOnEC2 376 | - 'EC2' 377 | - 'FARGATE' 378 | OmeroserverTaskExecutionRole: 379 | Type: AWS::IAM::Role 380 | Properties: 381 | AssumeRolePolicyDocument: 382 | Statement: 383 | - Action: 384 | - sts:AssumeRole 385 | Effect: Allow 386 | Principal: 387 | Service: ecs-tasks.amazonaws.com 388 | Version: '2012-10-17' 389 | ManagedPolicyArns: 390 | - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy 391 | - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 392 | Tags: 393 | - Key: project 394 | Value: omero-on-aws 395 | - Key: service 396 | Value: omeroserver 397 | OmeroserverTaskRole: 398 | Type: AWS::IAM::Role 399 | Properties: 400 | AssumeRolePolicyDocument: 401 | Statement: 402 | - Action: 403 | - sts:AssumeRole 404 | Effect: Allow 405 | Principal: 406 | Service: ecs-tasks.amazonaws.com 407 | Version: '2012-10-17' 408 | Policies: 409 | - PolicyName: OmeroserverOmeroVolumeMountPolicy 410 | PolicyDocument: 411 | Statement: 412 | - Action: 413 | - elasticfilesystem:ClientMount 414 | - elasticfilesystem:ClientWrite 415 | - elasticfilesystem:ClientRootAccess 416 | Condition: 417 | StringEquals: 418 | elasticfilesystem:AccessPointArn: !Ref NFSAccessPoint 419 | Effect: Allow 420 | Principal: {} 421 | Resource: 422 | - !Join 423 | - '' 424 | - - 'arn:aws:elasticfilesystem:' 425 | - !Ref 'AWS::Region' 426 | - ':' 427 | - !Ref 'AWS::AccountId' 428 | - ':file-system/' 429 | - !Ref EFSFileSystem 430 | - PolicyName: OmeroserverSSMPolicy 431 | PolicyDocument: 432 | Statement: 433 | - Action: 434 | - ssmmessages:CreateControlChannel 435 | - ssmmessages:CreateDataChannel 436 | - ssmmessages:OpenControlChannel 437 | - ssmmessages:OpenDataChannel 438 | Effect: Allow 439 | Resource: "*" 440 | Tags: 441 | - Key: project 442 | Value: omero-on-aws 443 | - Key: service 444 | Value: omeroserver 445 | ECSAutoScalingGroup: 446 | Type: AWS::AutoScaling::AutoScalingGroup 447 | Condition: runContainerOnEC2 448 | DependsOn: 449 | - MountTarget 450 | Properties: 451 | VPCZoneIdentifier: 452 | - !Ref PrivateSubnet1Id 453 | LaunchConfigurationName: !Ref 'ContainerInstances' 454 | MinSize: '1' 455 | MaxSize: '4' 456 | DesiredCapacity: !Ref NumberofEC2Instances 457 | CreationPolicy: 458 | ResourceSignal: 459 | Timeout: PT15M 460 | UpdatePolicy: 461 | AutoScalingReplacingUpdate: 462 | WillReplace: 'true' 463 | ContainerInstances: 464 | Type: AWS::AutoScaling::LaunchConfiguration 465 | Condition: runContainerOnEC2 466 | Properties: 467 | ImageId: !Ref LatestAmiId 468 | SecurityGroups: 469 | - !Ref OmeroSecurityGroup 470 | InstanceType: !Ref 'InstanceType' 471 | IamInstanceProfile: !Ref 'EC2InstanceProfile' 472 | KeyName: !If 473 | - runContainerOnEC2 474 | - !Ref 'KeyName' 475 | - !Ref 'AWS::NoValue' 476 | UserData: 477 | Fn::Base64: !Sub | 478 | #!/bin/bash -xe 479 | echo ECS_CLUSTER=${OMEROECSCluster} >> /etc/ecs/ecs.config 480 | yum install -y aws-cfn-bootstrap bzip2 unzip 481 | /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource ECSAutoScalingGroup --region ${AWS::Region} 482 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 483 | unzip awscliv2.zip 484 | ./aws/install 485 | yum install java-11-amazon-corretto-headless -y 486 | curl -LO https://anaconda.org/anaconda-adam/adam-installer/4.4.0/download/adam-installer-4.4.0-Linux-x86_64.sh 487 | bash adam-installer-4.4.0-Linux-x86_64.sh -b -p /opt/adam 488 | echo -e '\n# Anaconda Adam\nexport PATH=/opt/adam/bin:$PATH' >> /etc/bashrc 489 | source /etc/bashrc 490 | conda install -c anaconda libstdcxx-ng -y 491 | conda install -c anaconda libgcc-ng -y 492 | EC2Role: 493 | Type: AWS::IAM::Role 494 | Condition: runContainerOnEC2 495 | Properties: 496 | AssumeRolePolicyDocument: 497 | Statement: 498 | - Effect: Allow 499 | Principal: 500 | Service: 501 | - ec2.amazonaws.com 502 | Action: 503 | - sts:AssumeRole 504 | Path: / 505 | ManagedPolicyArns: 506 | - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role 507 | - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 508 | - arn:aws:iam::aws:policy/AmazonS3FullAccess 509 | Tags: 510 | - Key: project 511 | Value: omero-on-aws 512 | - Key: service 513 | Value: omeroserver 514 | EC2InstanceProfile: 515 | Type: AWS::IAM::InstanceProfile 516 | Condition: runContainerOnEC2 517 | Properties: 518 | Path: / 519 | Roles: [!Ref 'EC2Role'] 520 | 521 | OmerowebService: 522 | Type: AWS::ECS::Service 523 | DependsOn: 524 | - OmerowebHTTPSListener 525 | - OmerowebHTTPListener 526 | Properties: 527 | Cluster: !Ref 'OMEROECSCluster' 528 | DeploymentConfiguration: 529 | MaximumPercent: 200 530 | MinimumHealthyPercent: 100 531 | DeploymentController: 532 | Type: ECS 533 | DesiredCount: !Ref NumberofWebInstances 534 | LaunchType: 'FARGATE' 535 | EnableExecuteCommand: true 536 | LoadBalancers: 537 | - ContainerName: omeroweb 538 | ContainerPort: 4080 539 | TargetGroupArn: !Ref 'OmerowebTCP4080TargetGroup' 540 | NetworkConfiguration: 541 | AwsvpcConfiguration: 542 | AssignPublicIp: DISABLED 543 | SecurityGroups: 544 | - !Ref OmeroSecurityGroup 545 | Subnets: 546 | - !Ref 'PrivateSubnet1Id' 547 | - !Ref 'PrivateSubnet2Id' 548 | PropagateTags: SERVICE 549 | SchedulingStrategy: REPLICA 550 | ServiceRegistries: 551 | - RegistryArn: !GetAtt 'OmerowebServiceDiscoveryEntry.Arn' 552 | Tags: 553 | - Key: project 554 | Value: omero-on-aws 555 | - Key: service 556 | Value: omeroweb 557 | TaskDefinition: !Ref 'OmerowebTaskDefinition' 558 | 559 | HostedZoneRecord: 560 | DependsOn: 561 | - LoadBalancerSSLCert 562 | Type: AWS::Route53::RecordSet 563 | Properties: 564 | HostedZoneId: !Ref ExistingHostedZoneId 565 | Type: A 566 | Name: !Ref FullDomainName 567 | AliasTarget: 568 | DNSName: !GetAtt 'OMEROLoadBalancer.DNSName' 569 | HostedZoneId: !GetAtt 'OMEROLoadBalancer.CanonicalHostedZoneID' 570 | 571 | LoadBalancerSSLCert: 572 | Type: AWS::CertificateManager::Certificate 573 | Properties: 574 | DomainName: !Ref FullDomainName 575 | DomainValidationOptions: 576 | - DomainName: !Ref FullDomainName 577 | HostedZoneId: !Ref ExistingHostedZoneId 578 | ValidationMethod: DNS 579 | CertificateTransparencyLoggingPreference: ENABLED 580 | 581 | OmerowebHTTPSListener: 582 | Type: AWS::ElasticLoadBalancingV2::Listener 583 | Properties: 584 | Certificates: 585 | - CertificateArn: !Ref LoadBalancerSSLCert 586 | DefaultActions: 587 | - Type: forward 588 | TargetGroupArn: !Ref 'OmerowebTCP4080TargetGroup' 589 | LoadBalancerArn: !Ref 'OMEROLoadBalancer' 590 | Port: 443 591 | Protocol: HTTPS 592 | OmerowebHTTPListener: 593 | Type: AWS::ElasticLoadBalancingV2::Listener 594 | Properties: 595 | DefaultActions: 596 | - Type: redirect 597 | RedirectConfig: 598 | Protocol: HTTPS 599 | Port: '443' 600 | Host: '#{host}' 601 | Path: /#{path} 602 | Query: '#{query}' 603 | StatusCode: HTTP_301 604 | LoadBalancerArn: !Ref 'OMEROLoadBalancer' 605 | Port: 80 606 | Protocol: HTTP 607 | OmerowebTCP4080TargetGroup: 608 | Type: AWS::ElasticLoadBalancingV2::TargetGroup 609 | Properties: 610 | Port: 4080 611 | Protocol: HTTP 612 | TargetType: ip 613 | VpcId: !Ref VPCID 614 | HealthCheckEnabled: true 615 | HealthCheckProtocol: HTTP 616 | HealthCheckPort: 4080 617 | HealthCheckPath: /index/ 618 | Matcher: 619 | HttpCode: 200-302 620 | TargetGroupAttributes: 621 | - Key: stickiness.enabled 622 | Value: true 623 | - Key: stickiness.type 624 | Value: lb_cookie 625 | - Key: stickiness.lb_cookie.duration_seconds 626 | Value: 86500 627 | Tags: 628 | - Key: project 629 | Value: omero-on-aws 630 | OmerowebTaskDefinition: 631 | Type: AWS::ECS::TaskDefinition 632 | Properties: 633 | ContainerDefinitions: 634 | - Environment: 635 | - Name: OMEROHOST 636 | Value: !Sub omeroserver.${AWS::StackName}.ecscloudmap.org 637 | - Name: LOCALDOMAIN 638 | Value: !Join 639 | - '' 640 | - - !Ref 'AWS::Region' 641 | - .compute.internal 642 | - 'omero.local' 643 | Essential: true 644 | Image: !Ref OMEROWebContainerImage 645 | LinuxParameters: { initProcessEnabled: true } 646 | LogConfiguration: 647 | LogDriver: awslogs 648 | Options: 649 | awslogs-group: !Ref 'LogGroup' 650 | awslogs-region: !Ref 'AWS::Region' 651 | awslogs-stream-prefix: omeroweb 652 | Name: omeroweb 653 | PortMappings: 654 | - ContainerPort: 4080 655 | HostPort: 4080 656 | Protocol: tcp 657 | Cpu: !Ref OMEROWebContainerCPU 658 | Memory: !Ref OMEROWebContainerMemory 659 | ExecutionRoleArn: !Ref 'OmerowebTaskExecutionRole' 660 | TaskRoleArn: !Ref 'OmerowebTaskRole' 661 | Family: omero-web 662 | NetworkMode: awsvpc 663 | RequiresCompatibilities: 664 | - 'FARGATE' 665 | OmerowebTaskExecutionRole: 666 | Type: AWS::IAM::Role 667 | Properties: 668 | AssumeRolePolicyDocument: 669 | Statement: 670 | - Action: 671 | - sts:AssumeRole 672 | Effect: Allow 673 | Principal: 674 | Service: ecs-tasks.amazonaws.com 675 | Version: '2012-10-17' 676 | ManagedPolicyArns: 677 | - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy 678 | - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 679 | Tags: 680 | - Key: project 681 | Value: omero-on-aws 682 | - Key: service 683 | Value: omeroweb 684 | OmerowebTaskRole: 685 | Type: AWS::IAM::Role 686 | Properties: 687 | AssumeRolePolicyDocument: 688 | Statement: 689 | - Action: 690 | - sts:AssumeRole 691 | Effect: Allow 692 | Principal: 693 | Service: ecs-tasks.amazonaws.com 694 | Version: '2012-10-17' 695 | Policies: 696 | - PolicyName: OmerowebSSMPolicy 697 | PolicyDocument: 698 | Statement: 699 | - Action: 700 | - ssmmessages:CreateControlChannel 701 | - ssmmessages:CreateDataChannel 702 | - ssmmessages:OpenControlChannel 703 | - ssmmessages:OpenDataChannel 704 | Effect: Allow 705 | Resource: "*" 706 | 707 | Outputs: 708 | OMEROLoadBalancerHTTPEnpoint: 709 | Description: The HTTP endpoint of the OMEROLoadBalancer 710 | Value: !Join 711 | - '' 712 | - - 'https://' 713 | - !GetAtt OMEROLoadBalancer.DNSName 714 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMEROstackTLS_RW.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Metadata: 4 | 'AWS::CloudFormation::Interface': 5 | ParameterGroups: 6 | - Label: 7 | default: 'EFS Persistent Storage' 8 | Parameters: 9 | - OMEROStorageEFSNameTag 10 | - EFSBackup 11 | - EFSStorageArchiveAfter 12 | - KMSCMKId 13 | - Label: 14 | default: 'RDS Database' 15 | Parameters: 16 | - RDSDBInstanceSize 17 | - RDSDBStorage 18 | - RDSDStorageSize 19 | - RDSDBUserName 20 | - RDSDBBackupRetainInDays 21 | - RDSDBMultiAZ 22 | - Label: 23 | default: 'ECS' 24 | Parameters: 25 | - ECSContainerOnEC2 26 | - EC2KeyName 27 | - EC2InstanceType 28 | - NumberofECSEC2Instances 29 | - LoadBalancerAccessLogBucketName 30 | - CountofWebInstances 31 | - OMEROWebContainerCPUSize 32 | - OMEROWebContainerMemorySize 33 | - OMEROServerContainerCPUSize 34 | - OMEROServerContainerMemorySize 35 | - OMEROWebContainerImageParam 36 | - OMEROServerContainerImageParam 37 | - Label: 38 | default: 'Infrastructure' 39 | Parameters: 40 | - OMEROVPCID 41 | - DBECSPrivateSubnet1Id 42 | - DBECSPrivateSubnet2Id 43 | - LBPublicSubnet1Id 44 | - LBPublicSubnet2Id 45 | - CIDROMEROSecurityGroup 46 | - ExistingRoute53HostedZoneId 47 | - Route53FullDomainName 48 | 49 | Parameters: 50 | StackNamespace: 51 | Type: String 52 | Default: test 53 | OMEROVPCID: 54 | Description: ID of the VPC 55 | Type: AWS::EC2::VPC::Id 56 | DBECSPrivateSubnet1Id: 57 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 58 | Type: AWS::EC2::Subnet::Id 59 | DBECSPrivateSubnet2Id: 60 | Description: SubnetId, for Availability Zone 2 in the region in your VPC 61 | Type: AWS::EC2::Subnet::Id 62 | LBPublicSubnet1Id: 63 | Description: SubnetId, for Availability Zone 1 in the region in your VPC. The only one OMERO Server instance is deployed in this subnet. 64 | Type: AWS::EC2::Subnet::Id 65 | LBPublicSubnet2Id: 66 | Description: SubnetId, for Availability Zone 2 in the region in your VPC. None of OMERO Server instance is deployed in this subnet. 67 | Type: AWS::EC2::Subnet::Id 68 | CIDROMEROSecurityGroup: 69 | Type: String 70 | Default: '0.0.0.0/0' 71 | OMEROStorageEFSNameTag: 72 | Description: The name of the EFS volume 73 | Type: String 74 | MinLength: '1' 75 | Default: OMEROEFSvolume 76 | KMSCMKId: 77 | Description: The ID of the AWS KMS customer master key (CMK) to be used to protect the encrypted EFS and RDS storage. OPTIONAL if not specified, the default CMKs for Amazon EFS and RDS are used. 78 | Type: String 79 | EFSBackup: 80 | Type: String 81 | Description: whether enable EFS backup or not. EFS backup has extra associated cost. 82 | Default: ENABLED 83 | AllowedValues: [ENABLED, DISABLED] 84 | EFSStorageArchiveAfter: 85 | Type: String 86 | Description: A value that describes the period of time that a file is not accessed, after which it transitions to the IA storage class. 87 | Default: AFTER_90_DAYS 88 | AllowedValues: [AFTER_14_DAYS, AFTER_30_DAYS, AFTER_60_DAYS, AFTER_7_DAYS, AFTER_90_DAYS] 89 | RDSDBMultiAZ: 90 | Type: String 91 | Default: False 92 | Description: True or False for RDS Multiple Availability Zone 93 | RDSDBInstanceSize: 94 | Type: String 95 | Default: "db.t3.medium" 96 | RDSDBStorage: 97 | Type: String 98 | Default: "gp2" 99 | RDSDStorageSize: 100 | Type: Number 101 | Default: 20 102 | RDSDBUserName: 103 | Type: String 104 | Default: omero 105 | Description: OMERO Database User 106 | NoEcho: true 107 | RDSDBBackupRetainInDays: 108 | Type: Number 109 | Default: 30 110 | Description: The number of days for which automated backups are retained. Setting this parameter to a positive number (from 1 to 35) enables backups. Setting this parameter to 0 disables automated backups. 111 | LoadBalancerAccessLogBucketName: 112 | Type: String 113 | Default: ecs-loadbalancer-accesslog 114 | CountofWebInstances: 115 | Type: Number 116 | Default: 2 117 | Description: Number of OMERO Web containers 118 | OMEROServerContainerImageParam: 119 | Type: String 120 | Default: openmicroscopy/omero-server:latest 121 | OMEROWebContainerImageParam: 122 | Type: String 123 | Default: openmicroscopy/omero-web-standalone:latest 124 | OMEROWebContainerCPUSize: 125 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 126 | Type: Number 127 | Default: 2048 128 | AllowedValues: [256, 512, 1024, 2048, 4096] 129 | OMEROWebContainerMemorySize: 130 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 131 | Type: Number 132 | Default: 4096 133 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 134 | ECSContainerOnEC2: 135 | Type: String 136 | Default: N 137 | Description: will the ECS containers be hosted on ECS EC2 or Fargate launch type 138 | AllowedValues: [Y, N] 139 | EC2KeyName: 140 | Type: String 141 | Description: Name of an existing EC2 KeyPair to enable SSH access to the ECS EC2 instance hosting OMERO Server. OPTIONAL only for EC2 launch type. 142 | NumberofECSEC2Instances: 143 | Description: Number of EC2 instance to run container in ECS cluster. OPTIONAL only for EC2 lanuch type. 144 | Type: Number 145 | Default: 1 146 | EC2InstanceType: 147 | Description: ECS EC2 instance type. OPTIONAL only for EC2 launch type. 148 | Type: String 149 | Default: m4.xlarge 150 | AllowedValues: [t2.large, m3.large, 151 | m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, 152 | c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge, 153 | c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, 154 | r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] 155 | ConstraintDescription: Please choose a valid instance type. 156 | OMEROServerContainerCPUSize: 157 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 158 | Type: Number 159 | Default: 4096 160 | AllowedValues: [256, 512, 1024, 2048, 4096] 161 | OMEROServerContainerMemorySize: 162 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 163 | Type: Number 164 | Default: 10240 165 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 166 | ExistingRoute53HostedZoneId: 167 | Description: Existing HostedZone for Registered Domain used to validate SSL Certificate 168 | Type: AWS::Route53::HostedZone::Id 169 | Route53FullDomainName: 170 | Description: Enter the Fully Qualified Domain Name to validate SSL Certificate 171 | Type: String 172 | 173 | Resources: 174 | StorageStack: 175 | Type: 'AWS::CloudFormation::Stack' 176 | Properties: 177 | TemplateURL: https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROstorage.yaml 178 | Parameters: 179 | EFSNameTag: !Ref OMEROStorageEFSNameTag 180 | VPCID: !Ref OMEROVPCID 181 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 182 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 183 | CIDRblock4OMEROSecurityGroup: !Ref CIDROMEROSecurityGroup 184 | KMSCustomMasterKey: !Ref KMSCMKId 185 | EnableEFSBackup: !Ref EFSBackup 186 | EFSStorageInfrequentAcessAfter: !Ref EFSStorageArchiveAfter 187 | IsDBMultiAZ: !Ref RDSDBMultiAZ 188 | RDSDBInstanceClass: !Ref RDSDBInstanceSize 189 | RDSDBStorageType: !Ref RDSDBStorage 190 | RDSDBAllocatedStorage: !Ref RDSDStorageSize 191 | DBUser: !Ref RDSDBUserName 192 | RDSDBBackupRetentionDays: !Ref RDSDBBackupRetainInDays 193 | ECScontainerStack: 194 | Type: 'AWS::CloudFormation::Stack' 195 | Properties: 196 | TemplateURL: https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROonECS_ALBwithTLS_RW.yaml 197 | Parameters: 198 | Namespace: !Ref StackNamespace 199 | VPCID: !Ref OMEROVPCID 200 | PublicSubnet1Id: !Ref LBPublicSubnet1Id 201 | PublicSubnet2Id: !Ref LBPublicSubnet2Id 202 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 203 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 204 | KeyName: !Ref EC2KeyName 205 | LBAccessLogBucketName: !Ref LoadBalancerAccessLogBucketName 206 | NumberofWebInstances: !Ref CountofWebInstances 207 | OMEROWebContainerCPU: !Ref OMEROWebContainerCPUSize 208 | OMEROWebContainerMemory: !Ref OMEROWebContainerMemorySize 209 | ContainerOnEC2: !Ref ECSContainerOnEC2 210 | InstanceType: !Ref EC2InstanceType 211 | NumberofEC2Instances: !Ref NumberofECSEC2Instances 212 | OMEROServerContainerCPU: !Ref OMEROServerContainerCPUSize 213 | OMEROServerContainerMemory: !Ref OMEROServerContainerMemorySize 214 | OMEROServerContainerImage: !Ref OMEROServerContainerImageParam 215 | OMEROWebContainerImage: !Ref OMEROWebContainerImageParam 216 | DBUser: !Ref RDSDBUserName 217 | ExistingHostedZoneId: !Ref ExistingRoute53HostedZoneId 218 | FullDomainName: !Ref Route53FullDomainName 219 | LBSecurityGroup: 220 | Fn::GetAtt: 221 | - StorageStack 222 | - Outputs.LBSecurityGroup 223 | EFSSecurityGroup: 224 | Fn::GetAtt: 225 | - StorageStack 226 | - Outputs.EFSSecurityGroup 227 | OmeroSecurityGroup: 228 | Fn::GetAtt: 229 | - StorageStack 230 | - Outputs.OmeroSecurityGroup 231 | EFSFileSystem: 232 | Fn::GetAtt: 233 | - StorageStack 234 | - Outputs.EFSFileSystemID 235 | RDSEndpointAddress: 236 | Fn::GetAtt: 237 | - StorageStack 238 | - Outputs.RDSEndpointAddress 239 | RDSDatabaseSecret: 240 | Fn::GetAtt: 241 | - StorageStack 242 | - Outputs.RDSDatabaseSecret 243 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMEROstackTLS_RW_RO.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Metadata: 4 | 'AWS::CloudFormation::Interface': 5 | ParameterGroups: 6 | - Label: 7 | default: 'EFS Persistent Storage' 8 | Parameters: 9 | - OMEROStorageEFSNameTag 10 | - EFSBackup 11 | - EFSStorageArchiveAfter 12 | - KMSCMKId 13 | - Label: 14 | default: 'RDS Database' 15 | Parameters: 16 | - RDSDBInstanceSize 17 | - RDSDBStorage 18 | - RDSDStorageSize 19 | - RDSDBUserName 20 | - RDSDBBackupRetainInDays 21 | - RDSDBMultiAZ 22 | - Label: 23 | default: 'ECS' 24 | Parameters: 25 | - ECSContainerOnEC2 26 | - EC2KeyName 27 | - EC2InstanceType 28 | - NumberofECSEC2Instances 29 | - LoadBalancerAccessLogBucketName 30 | - CountofWebInstances 31 | - OMEROWebContainerCPUSize 32 | - OMEROWebContainerMemorySize 33 | - OMEROServerContainerCPUSize 34 | - OMEROServerContainerMemorySize 35 | - OMEROWebContainerImageParam 36 | - OMEROServerContainerImageParam 37 | - Label: 38 | default: 'Infrastructure' 39 | Parameters: 40 | - OMEROVPCID 41 | - DBECSPrivateSubnet1Id 42 | - DBECSPrivateSubnet2Id 43 | - LBPublicSubnet1Id 44 | - LBPublicSubnet2Id 45 | - CIDROMEROSecurityGroup 46 | 47 | Parameters: 48 | StackNamespace: 49 | Type: String 50 | Default: test 51 | OMEROVPCID: 52 | Description: ID of the VPC 53 | Type: AWS::EC2::VPC::Id 54 | DBECSPrivateSubnet1Id: 55 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 56 | Type: AWS::EC2::Subnet::Id 57 | DBECSPrivateSubnet2Id: 58 | Description: SubnetId, for Availability Zone 2 in the region in your VPC 59 | Type: AWS::EC2::Subnet::Id 60 | LBPublicSubnet1Id: 61 | Description: SubnetId, for Availability Zone 1 in the region in your VPC. The only one OMERO Server instance is deployed in this subnet. 62 | Type: AWS::EC2::Subnet::Id 63 | LBPublicSubnet2Id: 64 | Description: SubnetId, for Availability Zone 2 in the region in your VPC. None of OMERO Server instance is deployed in this subnet. 65 | Type: AWS::EC2::Subnet::Id 66 | CIDROMEROSecurityGroup: 67 | Type: String 68 | Default: '0.0.0.0/0' 69 | OMEROStorageEFSNameTag: 70 | Description: The name of the EFS volume 71 | Type: String 72 | MinLength: '1' 73 | Default: OMEROEFSvolume 74 | KMSCMKId: 75 | Description: The ID of the AWS KMS customer master key (CMK) to be used to protect the encrypted EFS and RDS storage. OPTIONAL if not specified, the default CMKs for Amazon EFS and RDS are used. 76 | Type: String 77 | EFSBackup: 78 | Type: String 79 | Description: whether enable EFS backup or not. EFS backup has extra associated cost. 80 | Default: ENABLED 81 | AllowedValues: [ENABLED, DISABLED] 82 | EFSStorageArchiveAfter: 83 | Type: String 84 | Description: A value that describes the period of time that a file is not accessed, after which it transitions to the IA storage class. 85 | Default: AFTER_90_DAYS 86 | AllowedValues: [AFTER_14_DAYS, AFTER_30_DAYS, AFTER_60_DAYS, AFTER_7_DAYS, AFTER_90_DAYS] 87 | RDSDBMultiAZ: 88 | Type: String 89 | Default: False 90 | Description: True or False for RDS Multiple Availability Zone 91 | RDSDBInstanceSize: 92 | Type: String 93 | Default: "db.t3.medium" 94 | RDSDBStorage: 95 | Type: String 96 | Default: "gp2" 97 | RDSDStorageSize: 98 | Type: Number 99 | Default: 20 100 | RDSDBUserName: 101 | Type: String 102 | Default: omero 103 | Description: OMERO Database User 104 | NoEcho: true 105 | RDSDBBackupRetainInDays: 106 | Type: Number 107 | Default: 30 108 | Description: The number of days for which automated backups are retained. Setting this parameter to a positive number (from 1 to 35) enables backups. Setting this parameter to 0 disables automated backups. 109 | LoadBalancerAccessLogBucketName: 110 | Type: String 111 | Default: omero-ecs-loadbalancer-accesslog 112 | OMEROServerContainerImageParam: 113 | Type: String 114 | Default: openmicroscopy/omero-server:latest 115 | OMEROWebContainerImageParam: 116 | Type: String 117 | Default: openmicroscopy/omero-web-standalone:latest 118 | CountofWebInstances: 119 | Type: Number 120 | Default: 2 121 | Description: Number of OMERO Web containers 122 | OMEROWebContainerCPUSize: 123 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 124 | Type: Number 125 | Default: 2048 126 | AllowedValues: [256, 512, 1024, 2048, 4096] 127 | OMEROWebContainerMemorySize: 128 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 129 | Type: Number 130 | Default: 4096 131 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 132 | CountofEC2Instances: 133 | Type: Number 134 | Default: 2 135 | Description: Number of EC2 instances hosting OMERO server containers 136 | CountofReadOnlyServerInstances: 137 | Type: Number 138 | Default: 1 139 | Description: Number of OMERO ReadOnly Server containers 140 | ECSContainerOnEC2: 141 | Type: String 142 | Default: N 143 | Description: will the ECS containers be hosted on ECS EC2 or Fargate launch type 144 | AllowedValues: [Y, N] 145 | EC2KeyName: 146 | Type: String 147 | Description: Name of an existing EC2 KeyPair to enable SSH access to the ECS EC2 instance hosting OMERO Server. OPTIONAL only for EC2 launch type. 148 | NumberofECSEC2Instances: 149 | Description: Number of EC2 instance to run container in ECS cluster. OPTIONAL only for EC2 lanuch type. 150 | Type: Number 151 | Default: 4 152 | EC2InstanceType: 153 | Description: EC2 instance type 154 | Type: String 155 | Default: m4.xlarge 156 | AllowedValues: [t2.large, m3.large, 157 | m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, 158 | c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge, 159 | c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, 160 | r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] 161 | ConstraintDescription: Please choose a valid instance type. 162 | OMEROServerContainerCPUSize: 163 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 164 | Type: Number 165 | Default: 2048 166 | AllowedValues: [256, 512, 1024, 2048, 4096] 167 | OMEROServerContainerMemorySize: 168 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 169 | Type: Number 170 | Default: 4096 171 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 172 | ExistingRoute53HostedZoneId: 173 | Description: Existing HostedZone for Registered Domain used to validate SSL Certificate 174 | Type: AWS::Route53::HostedZone::Id 175 | Route53FullDomainName: 176 | Description: Enter the Fully Qualified Domain Name to validate SSL Certificate 177 | Type: String 178 | 179 | Resources: 180 | StorageStack: 181 | Type: 'AWS::CloudFormation::Stack' 182 | Properties: 183 | TemplateURL: https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROstorage.yaml 184 | Parameters: 185 | EFSNameTag: !Ref OMEROStorageEFSNameTag 186 | VPCID: !Ref OMEROVPCID 187 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 188 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 189 | CIDRblock4OMEROSecurityGroup: !Ref CIDROMEROSecurityGroup 190 | KMSCustomMasterKey: !Ref KMSCMKId 191 | EnableEFSBackup: !Ref EFSBackup 192 | EFSStorageInfrequentAcessAfter: !Ref EFSStorageArchiveAfter 193 | IsDBMultiAZ: !Ref RDSDBMultiAZ 194 | RDSDBInstanceClass: !Ref RDSDBInstanceSize 195 | RDSDBStorageType: !Ref RDSDBStorage 196 | RDSDBAllocatedStorage: !Ref RDSDStorageSize 197 | DBUser: !Ref RDSDBUserName 198 | RDSDBBackupRetentionDays: !Ref RDSDBBackupRetainInDays 199 | ECScontainerStack: 200 | Type: 'AWS::CloudFormation::Stack' 201 | Properties: 202 | TemplateURL: https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROonECS_ALBwithTLS_RW_RO.yml 203 | Parameters: 204 | Namespace: !Ref StackNamespace 205 | VPCID: !Ref OMEROVPCID 206 | PublicSubnet1Id: !Ref LBPublicSubnet1Id 207 | PublicSubnet2Id: !Ref LBPublicSubnet2Id 208 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 209 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 210 | KeyName: !Ref EC2KeyName 211 | LBAccessLogBucketName: !Ref LoadBalancerAccessLogBucketName 212 | NumberofWebInstances: !Ref CountofWebInstances 213 | OMEROWebContainerCPU: !Ref OMEROWebContainerCPUSize 214 | OMEROWebContainerMemory: !Ref OMEROWebContainerMemorySize 215 | NumberofEC2Instances: !Ref CountofEC2Instances 216 | NumberofReadOnlyServerInstances: !Ref CountofReadOnlyServerInstances 217 | ContainerOnEC2: !Ref ECSContainerOnEC2 218 | InstanceType: !Ref EC2InstanceType 219 | NumberofEC2Instances: !Ref NumberofECSEC2Instances 220 | OMEROServerContainerCPU: !Ref OMEROServerContainerCPUSize 221 | OMEROServerContainerMemory: !Ref OMEROServerContainerMemorySize 222 | OMEROServerContainerImage: !Ref OMEROServerContainerImageParam 223 | OMEROWebContainerImage: !Ref OMEROWebContainerImageParam 224 | DBUser: !Ref RDSDBUserName 225 | ExistingHostedZoneId: !Ref ExistingRoute53HostedZoneId 226 | FullDomainName: !Ref Route53FullDomainName 227 | LBSecurityGroup: 228 | Fn::GetAtt: 229 | - StorageStack 230 | - Outputs.LBSecurityGroup 231 | EFSSecurityGroup: 232 | Fn::GetAtt: 233 | - StorageStack 234 | - Outputs.EFSSecurityGroup 235 | OmeroSecurityGroup: 236 | Fn::GetAtt: 237 | - StorageStack 238 | - Outputs.OmeroSecurityGroup 239 | OmeroFilesystem: 240 | Fn::GetAtt: 241 | - StorageStack 242 | - Outputs.EFSFileSystemID 243 | RDSEndpointAddress: 244 | Fn::GetAtt: 245 | - StorageStack 246 | - Outputs.RDSEndpointAddress 247 | RDSDatabaseSecret: 248 | Fn::GetAtt: 249 | - StorageStack 250 | - Outputs.RDSDatabaseSecret 251 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMEROstack_RW.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Metadata: 4 | 'AWS::CloudFormation::Interface': 5 | ParameterGroups: 6 | - Label: 7 | default: 'EFS Persistent Storage' 8 | Parameters: 9 | - OMEROStorageEFSNameTag 10 | - EFSBackup 11 | - EFSStorageArchiveAfter 12 | - KMSCMKId 13 | - Label: 14 | default: 'RDS Database' 15 | Parameters: 16 | - RDSDBInstanceSize 17 | - RDSDBStorage 18 | - RDSDStorageSize 19 | - RDSDBUserName 20 | - RDSDBBackupRetainInDays 21 | - RDSDBMultiAZ 22 | - Label: 23 | default: 'ECS' 24 | Parameters: 25 | - ECSContainerOnEC2 26 | - EC2KeyName 27 | - EC2InstanceType 28 | - NumberofECSEC2Instances 29 | - LoadBalancerAccessLogBucketName 30 | - CountofWebInstances 31 | - OMEROWebContainerCPUSize 32 | - OMEROWebContainerMemorySize 33 | - OMEROServerContainerCPUSize 34 | - OMEROServerContainerMemorySize 35 | - OMEROWebContainerImageParam 36 | - OMEROServerContainerImageParam 37 | - Label: 38 | default: 'Infrastructure' 39 | Parameters: 40 | - OMEROVPCID 41 | - DBECSPrivateSubnet1Id 42 | - DBECSPrivateSubnet2Id 43 | - LBPublicSubnet1Id 44 | - LBPublicSubnet2Id 45 | - CIDROMEROSecurityGroup 46 | 47 | Parameters: 48 | StackNamespace: 49 | Type: String 50 | Default: test 51 | OMEROVPCID: 52 | Description: ID of the VPC 53 | Type: AWS::EC2::VPC::Id 54 | DBECSPrivateSubnet1Id: 55 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 56 | Type: AWS::EC2::Subnet::Id 57 | DBECSPrivateSubnet2Id: 58 | Description: SubnetId, for Availability Zone 2 in the region in your VPC 59 | Type: AWS::EC2::Subnet::Id 60 | LBPublicSubnet1Id: 61 | Description: SubnetId, for Availability Zone 1 in the region in your VPC. The only one OMERO Server instance is deployed in this subnet. 62 | Type: AWS::EC2::Subnet::Id 63 | LBPublicSubnetAZ1Name: 64 | Description: Availability Zone Name for Public Subnet 1. 65 | Type: String 66 | LBPublicSubnet2Id: 67 | Description: SubnetId, for Availability Zone 2 in the region in your VPC. None of OMERO Server instance is deployed in this subnet. 68 | Type: AWS::EC2::Subnet::Id 69 | LBPublicSubnetAZ2Name: 70 | Description: Availability Zone Name for Public Subnet 2. 71 | Type: String 72 | CIDROMEROSecurityGroup: 73 | Type: String 74 | Default: '0.0.0.0/0' 75 | OMEROStorageEFSNameTag: 76 | Description: The name of the EFS volume 77 | Type: String 78 | MinLength: '1' 79 | Default: OMEROEFSvolume 80 | KMSCMKId: 81 | Description: The ID of the AWS KMS customer master key (CMK) to be used to protect the encrypted EFS and RDS storage. OPTIONAL if not specified, the default CMKs for Amazon EFS and RDS are used. 82 | Type: String 83 | EFSBackup: 84 | Type: String 85 | Description: whether enable EFS backup or not. EFS backup has extra associated cost. 86 | Default: ENABLED 87 | AllowedValues: [ENABLED, DISABLED] 88 | EFSStorageArchiveAfter: 89 | Type: String 90 | Description: A value that describes the period of time that a file is not accessed, after which it transitions to the IA storage class. 91 | Default: AFTER_90_DAYS 92 | AllowedValues: [AFTER_14_DAYS, AFTER_30_DAYS, AFTER_60_DAYS, AFTER_7_DAYS, AFTER_90_DAYS] 93 | RDSDBMultiAZ: 94 | Type: String 95 | Default: False 96 | Description: True or False for RDS Multiple Availability Zone 97 | RDSDBInstanceSize: 98 | Type: String 99 | Default: "db.t3.medium" 100 | RDSDBStorage: 101 | Type: String 102 | Default: "gp2" 103 | RDSDStorageSize: 104 | Type: Number 105 | Default: 20 106 | RDSDBUserName: 107 | Type: String 108 | Default: omero 109 | Description: OMERO Database User 110 | NoEcho: true 111 | RDSDBBackupRetainInDays: 112 | Type: Number 113 | Default: 30 114 | Description: The number of days for which automated backups are retained. Setting this parameter to a positive number (from 1 to 35) enables backups. Setting this parameter to 0 disables automated backups. 115 | LoadBalancerAccessLogBucketName: 116 | Type: String 117 | Default: ecs-loadbalancer-accesslog 118 | CountofWebInstances: 119 | Type: Number 120 | Default: 2 121 | Description: Number of OMERO Web containers 122 | OMEROServerContainerImageParam: 123 | Type: String 124 | Default: openmicroscopy/omero-server:latest 125 | OMEROWebContainerImageParam: 126 | Type: String 127 | Default: openmicroscopy/omero-web-standalone:latest 128 | OMEROWebContainerCPUSize: 129 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 130 | Type: Number 131 | Default: 2048 132 | AllowedValues: [256, 512, 1024, 2048, 4096] 133 | OMEROWebContainerMemorySize: 134 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 135 | Type: Number 136 | Default: 4096 137 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 138 | ECSContainerOnEC2: 139 | Type: String 140 | Default: N 141 | Description: will the ECS containers be hosted on ECS EC2 or Fargate launch type 142 | AllowedValues: [Y, N] 143 | EC2KeyName: 144 | Type: String 145 | Description: Name of an existing EC2 KeyPair to enable SSH access to the ECS EC2 instance hosting OMERO Server. OPTIONAL only for EC2 launch type. 146 | NumberofECSEC2Instances: 147 | Description: Number of EC2 instance to run container in ECS cluster. OPTIONAL only for EC2 lanuch type. 148 | Type: Number 149 | Default: 1 150 | EC2InstanceType: 151 | Description: ECS EC2 instance type. OPTIONAL only for EC2 launch type. 152 | Type: String 153 | Default: m4.xlarge 154 | AllowedValues: [t2.large, m3.large, 155 | m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, 156 | c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge, 157 | c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, 158 | r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] 159 | ConstraintDescription: Please choose a valid instance type. 160 | OMEROServerContainerCPUSize: 161 | Description: The number of cpu units the Amazon ECS container agent will reserve for the container. 162 | Type: Number 163 | Default: 4096 164 | AllowedValues: [256, 512, 1024, 2048, 4096] 165 | OMEROServerContainerMemorySize: 166 | Description: The amount (in MiB) of memory to present to the container. . Memory should be at least two times of vCPU unit according to documentation. 167 | Type: Number 168 | Default: 10240 169 | AllowedValues: [512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 11264, 12288, 13312, 14336, 15360, 16384, 30720] 170 | 171 | Conditions: 172 | runContainerOnEC2: !Equals [ !Ref 'ECSContainerOnEC2', 'Y' ] 173 | 174 | Resources: 175 | StorageStack: 176 | Type: 'AWS::CloudFormation::Stack' 177 | Properties: 178 | TemplateURL: https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROstorage.yaml 179 | Parameters: 180 | EFSNameTag: !Ref OMEROStorageEFSNameTag 181 | VPCID: !Ref OMEROVPCID 182 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 183 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 184 | CIDRblock4OMEROSecurityGroup: !Ref CIDROMEROSecurityGroup 185 | KMSCustomMasterKey: !Ref KMSCMKId 186 | EnableEFSBackup: !Ref EFSBackup 187 | EFSStorageInfrequentAcessAfter: !Ref EFSStorageArchiveAfter 188 | IsDBMultiAZ: !Ref RDSDBMultiAZ 189 | RDSDBInstanceClass: !Ref RDSDBInstanceSize 190 | RDSDBStorageType: !Ref RDSDBStorage 191 | RDSDBAllocatedStorage: !Ref RDSDStorageSize 192 | DBUser: !Ref RDSDBUserName 193 | RDSDBBackupRetentionDays: !Ref RDSDBBackupRetainInDays 194 | ECScontainerStack: 195 | Type: 'AWS::CloudFormation::Stack' 196 | Properties: 197 | TemplateURL: https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROonECS_RW.yaml 198 | Parameters: 199 | Namespace: !Ref StackNamespace 200 | VPCID: !Ref OMEROVPCID 201 | PublicSubnet1Id: !Ref LBPublicSubnet1Id 202 | PublicSubnet2Id: !Ref LBPublicSubnet2Id 203 | PrivateSubnet1Id: !Ref DBECSPrivateSubnet1Id 204 | PrivateSubnet2Id: !Ref DBECSPrivateSubnet2Id 205 | KeyName: !Ref EC2KeyName 206 | LBAccessLogBucketName: !Ref LoadBalancerAccessLogBucketName 207 | NumberofWebInstances: !Ref CountofWebInstances 208 | OMEROWebContainerCPU: !Ref OMEROWebContainerCPUSize 209 | OMEROWebContainerMemory: !Ref OMEROWebContainerMemorySize 210 | ContainerOnEC2: !Ref ECSContainerOnEC2 211 | InstanceType: !Ref EC2InstanceType 212 | NumberofEC2Instances: !Ref NumberofECSEC2Instances 213 | OMEROServerContainerCPU: !Ref OMEROServerContainerCPUSize 214 | OMEROServerContainerMemory: !Ref OMEROServerContainerMemorySize 215 | OMEROServerContainerImage: !Ref OMEROServerContainerImageParam 216 | OMEROWebContainerImage: !Ref OMEROWebContainerImageParam 217 | DBUser: !Ref RDSDBUserName 218 | LBSecurityGroup: 219 | Fn::GetAtt: 220 | - StorageStack 221 | - Outputs.LBSecurityGroup 222 | EFSSecurityGroup: 223 | Fn::GetAtt: 224 | - StorageStack 225 | - Outputs.EFSSecurityGroup 226 | OmeroSecurityGroup: 227 | Fn::GetAtt: 228 | - StorageStack 229 | - Outputs.OmeroSecurityGroup 230 | EFSFileSystem: 231 | Fn::GetAtt: 232 | - StorageStack 233 | - Outputs.EFSFileSystemID 234 | RDSEndpointAddress: 235 | Fn::GetAtt: 236 | - StorageStack 237 | - Outputs.RDSEndpointAddress 238 | RDSDatabaseSecret: 239 | Fn::GetAtt: 240 | - StorageStack 241 | - Outputs.RDSDatabaseSecret 242 | MonitoringStack: 243 | Type: 'AWS::CloudFormation::Stack' 244 | Properties: 245 | TemplateURL: https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROonECS_Monitoring.yaml 246 | Parameters: 247 | DashboardName: !Join ['-', [!Ref 'AWS::StackName', !Ref StackNamespace ]] 248 | ApplicationELBNameSpace: 249 | Fn::GetAtt: 250 | - ECScontainerStack 251 | - Outputs.ApplicationELBNameSpace 252 | ApplicationELBAZ1Name: !Ref LBPublicSubnetAZ1Name 253 | ApplicationELBAZ2Name: !Ref LBPublicSubnetAZ2Name 254 | ApplicationELBTargetGroupNameSpace: 255 | Fn::GetAtt: 256 | - ECScontainerStack 257 | - Outputs.ApplicationELBTargetGroupNameSpace 258 | EC2AutoScalingGroupName: 259 | Fn::If: 260 | - runContainerOnEC2 261 | - Fn::GetAtt: ECScontainerStack.Outputs.EC2AutoScalingGroupName 262 | - !Ref StackNamespace 263 | RDSDBInstanceIdentifier: 264 | Fn::GetAtt: 265 | - StorageStack 266 | - Outputs.RDSDBInstanceIdentifier 267 | ECSClusterName: 268 | Fn::GetAtt: 269 | - ECScontainerStack 270 | - Outputs.ECSClusterName 271 | ContainerOnEC2: !Ref ECSContainerOnEC2 272 | 273 | Outputs: 274 | OMEROLoadBalancerHTTPEnpoint: 275 | Description: The HTTP endpoint of the OMEROLoadBalancer 276 | Value: 277 | Fn::GetAtt: 278 | - ECScontainerStack 279 | - Outputs.OMEROLoadBalancerHTTPEnpoint -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/OMEROstorage.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | 3 | Parameters: 4 | VPCID: 5 | Description: ID of the VPC 6 | Type: AWS::EC2::VPC::Id 7 | PrivateSubnet1Id: 8 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 9 | Type: AWS::EC2::Subnet::Id 10 | PrivateSubnet2Id: 11 | Description: SubnetId, for Availability Zone 2 in the region in your VPC 12 | Type: AWS::EC2::Subnet::Id 13 | IsDBMultiAZ: 14 | Type: String 15 | Default: False 16 | CIDRblock4OMEROSecurityGroup: 17 | Type: String 18 | Default: '0.0.0.0/0' 19 | EFSNameTag: 20 | Description: The name of the EFS volume 21 | Type: String 22 | MinLength: '1' 23 | Default: OMEROEFSvolume 24 | KMSCustomMasterKey: 25 | Description: The ID of the AWS KMS customer master key (CMK) to be used to protect the encrypted EFS and RDS storage. OPTIONAL if not specified, the default CMKs for Amazon EFS and RDS are used. 26 | Type: String 27 | EnableEFSBackup: 28 | Type: String 29 | Description: whether enable EFS backup or not. EFS backup has extra associated cost. 30 | Default: ENABLED 31 | AllowedValues: [ENABLED, DISABLED] 32 | EFSStorageInfrequentAcessAfter: 33 | Type: String 34 | Description: A value that describes the period of time that a file is not accessed, after which it transitions to the IA storage class. 35 | Default: AFTER_90_DAYS 36 | AllowedValues: [AFTER_14_DAYS, AFTER_30_DAYS, AFTER_60_DAYS, AFTER_7_DAYS, AFTER_90_DAYS] 37 | RDSDBInstanceClass: 38 | Type: String 39 | Default: "db.t3.medium" 40 | Description: Database Instance Class. For more information, go to https://aws.amazon.com/rds/instance-types/ 41 | AllowedValues: 42 | - db.t3.medium 43 | - db.r4.large 44 | - db.r4.xlarge 45 | - db.r4.2xlarge 46 | - db.r4.4xlarge 47 | - db.r4.8xlarge 48 | - db.r4.16xlarge 49 | - db.r5.large 50 | - db.r5.xlarge 51 | - db.r5.2xlarge 52 | - db.r5.4xlarge 53 | - db.r5.8xlarge 54 | - db.r5.12xlarge 55 | - db.r5.16xlarge 56 | - db.r5.24xlarge 57 | RDSDBStorageType: 58 | Type: String 59 | Default: "gp2" 60 | RDSDBAllocatedStorage: 61 | Type: Number 62 | Default: 20 63 | DBUser: 64 | Type: String 65 | Default: omero 66 | Description: OMERO Database User 67 | NoEcho: true 68 | RDSDBBackupRetentionDays: 69 | Type: Number 70 | Default: 30 71 | Description: The number of days for which automated backups are retained. Setting this parameter to a positive number (from 1 to 35) enables backups. Setting this parameter to 0 disables automated backups. 72 | 73 | Conditions: 74 | HasKMSCMK: !Not [!Equals ["", !Ref KMSCustomMasterKey]] 75 | 76 | Resources: 77 | RDSDatabaseSecret: 78 | Type: AWS::SecretsManager::Secret 79 | Properties: 80 | Name: !Sub ${AWS::StackName}-RDSDatabaseSecret 81 | Description: !Join ['', ['RDS Database Master User Secret ', 'for CloudFormation Stack ', !Ref 'AWS::StackName']] 82 | Tags: 83 | - Key: project 84 | Value: omero-on-aws 85 | GenerateSecretString: 86 | SecretStringTemplate: !Join ['', ['{"username": "', !Ref DBUser, '"}']] 87 | GenerateStringKey: "password" 88 | ExcludeCharacters: '"@/\' 89 | PasswordLength: 16 90 | SMSecretRDSDBAttachment: 91 | Type: AWS::SecretsManager::SecretTargetAttachment 92 | Properties: 93 | SecretId: !Ref RDSDatabaseSecret 94 | TargetId: !Ref RDSInstance 95 | TargetType: AWS::RDS::DBInstance 96 | LBSecurityGroup: 97 | Type: AWS::EC2::SecurityGroup 98 | Properties: 99 | GroupDescription: Load Balancer Security Group 100 | GroupName: !Sub ${AWS::StackName}-LBSecurityGroup 101 | SecurityGroupIngress: 102 | - CidrIp: !Ref CIDRblock4OMEROSecurityGroup 103 | Description: omeroweb:4080/tcp 104 | FromPort: 80 105 | IpProtocol: TCP 106 | ToPort: 80 107 | - CidrIp: !Ref CIDRblock4OMEROSecurityGroup 108 | Description: omeroweb:443/https 109 | FromPort: 443 110 | IpProtocol: TCP 111 | ToPort: 443 112 | Tags: 113 | - Key: project 114 | Value: omero-on-aws 115 | - Key: network 116 | Value: loadbalancer 117 | VpcId: !Ref VPCID 118 | OmeroSecurityGroup: 119 | Type: AWS::EC2::SecurityGroup 120 | Properties: 121 | GroupDescription: OMERO Security Group 122 | GroupName: !Sub ${AWS::StackName}-OmeroSecurityGroup 123 | SecurityGroupIngress: 124 | - CidrIp: !Ref CIDRblock4OMEROSecurityGroup 125 | Description: omeroserver:4063/tcp 126 | FromPort: 4063 127 | IpProtocol: TCP 128 | ToPort: 4063 129 | - CidrIp: !Ref CIDRblock4OMEROSecurityGroup 130 | Description: omeroserver:4064/tcp 131 | FromPort: 4064 132 | IpProtocol: TCP 133 | ToPort: 4064 134 | - CidrIp: !Ref CIDRblock4OMEROSecurityGroup 135 | Description: omeroserver:14064/tcp 136 | FromPort: 14064 137 | IpProtocol: TCP 138 | ToPort: 14064 139 | - CidrIp: !Ref CIDRblock4OMEROSecurityGroup 140 | Description: ssh 141 | FromPort: 22 142 | IpProtocol: TCP 143 | ToPort: 22 144 | - SourceSecurityGroupId: !Ref LBSecurityGroup 145 | Description: omeroweb:4080/tcp 146 | FromPort: 4080 147 | IpProtocol: TCP 148 | ToPort: 4080 149 | Tags: 150 | - Key: project 151 | Value: omero-on-aws 152 | - Key: network 153 | Value: omero 154 | VpcId: !Ref VPCID 155 | OmeroSecurityGroupIngress: 156 | Type: AWS::EC2::SecurityGroupIngress 157 | Properties: 158 | Description: Allow communication within omero network 159 | GroupId: !Ref OmeroSecurityGroup 160 | IpProtocol: '-1' 161 | SourceSecurityGroupId: !Ref OmeroSecurityGroup 162 | RDSSecurityGroup: 163 | Type: AWS::EC2::SecurityGroup 164 | Properties: 165 | GroupDescription: RDS Security Group 166 | GroupName: !Sub ${AWS::StackName}-RDSSecurityGroup 167 | SecurityGroupIngress: 168 | - SourceSecurityGroupId: !Ref OmeroSecurityGroup 169 | Description: postgres:5432/tcp 170 | FromPort: 5432 171 | IpProtocol: TCP 172 | ToPort: 5432 173 | Tags: 174 | - Key: project 175 | Value: omero-on-aws 176 | - Key: network 177 | Value: rds 178 | VpcId: !Ref VPCID 179 | EFSSecurityGroup: 180 | Type: AWS::EC2::SecurityGroup 181 | Properties: 182 | GroupDescription: EFS Security Group 183 | GroupName: !Sub ${AWS::StackName}-EFSSecurityGroup 184 | SecurityGroupIngress: 185 | - SourceSecurityGroupId: !Ref OmeroSecurityGroup 186 | Description: efs:4063/tcp 187 | FromPort: 2049 188 | IpProtocol: TCP 189 | ToPort: 2049 190 | Tags: 191 | - Key: project 192 | Value: omero-on-aws 193 | - Key: network 194 | Value: efs 195 | VpcId: !Ref VPCID 196 | 197 | FileSystem: 198 | Type: AWS::EFS::FileSystem 199 | DeletionPolicy: Retain ## or Delete/Snapshot 200 | Properties: 201 | Encrypted: True 202 | KmsKeyId: !If [HasKMSCMK, !Ref KMSCustomMasterKey, !Ref AWS::NoValue] 203 | BackupPolicy: 204 | Status: !Ref EnableEFSBackup 205 | LifecyclePolicies: 206 | - TransitionToIA: !Ref EFSStorageInfrequentAcessAfter 207 | FileSystemTags: 208 | - Key: Name 209 | Value: !Ref 'EFSNameTag' 210 | 211 | DBSubnetGroup: 212 | Type: AWS::RDS::DBSubnetGroup 213 | Properties: 214 | DBSubnetGroupDescription: DBSubnetGroup for RDS instances 215 | SubnetIds: 216 | - !Ref PrivateSubnet1Id 217 | - !Ref PrivateSubnet2Id 218 | RDSInstance: 219 | Type: AWS::RDS::DBInstance 220 | DeletionPolicy: Retain ## or Delete/Snapshot 221 | Properties: 222 | DBInstanceIdentifier: !Sub ${AWS::StackName}-omero-instance 223 | DBName: omero 224 | DBInstanceClass: !Ref RDSDBInstanceClass 225 | StorageType: !Ref RDSDBStorageType 226 | StorageEncrypted: True 227 | KmsKeyId: !If [HasKMSCMK, !Ref KMSCustomMasterKey, !Ref AWS::NoValue] 228 | AllocatedStorage: !Ref RDSDBAllocatedStorage 229 | Engine: postgres 230 | EngineVersion: 11 231 | MasterUsername: !Ref DBUser 232 | MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref RDSDatabaseSecret, ':SecretString:password}}' ]] 233 | PubliclyAccessible: False 234 | MultiAZ: !Ref IsDBMultiAZ 235 | Tags: 236 | - Key: project 237 | Value: omero-on-aws 238 | VPCSecurityGroups: 239 | - !Ref RDSSecurityGroup 240 | DBSubnetGroupName: !Ref DBSubnetGroup 241 | BackupRetentionPeriod: !Ref RDSDBBackupRetentionDays 242 | Tags: 243 | - Key: project 244 | Value: omero-on-aws 245 | 246 | Outputs: 247 | EFSFileSystemID: 248 | Value: !Ref FileSystem 249 | LBSecurityGroup: 250 | Value: !Ref LBSecurityGroup 251 | OmeroSecurityGroup: 252 | Value: !Ref OmeroSecurityGroup 253 | EFSSecurityGroup: 254 | Value: !Ref EFSSecurityGroup 255 | RDSDBInstanceIdentifier: 256 | Value: !Select [0, !Split [".", !GetAtt 'RDSInstance.Endpoint.Address']] 257 | RDSEndpointAddress: 258 | Value: !GetAtt 'RDSInstance.Endpoint.Address' 259 | RDSDatabaseSecret: 260 | Value: !Ref RDSDatabaseSecret 261 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/ec2s3filegateway.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Parameters: 4 | Namespace: 5 | Description: A string of 4-20 lowercase letters and digits, starting with a letter. Included in resource names, allowing multiple deployments. 6 | Default: filegateway 7 | Type: String 8 | AllowedPattern: "^[a-z]{1}[a-z0-9]{3,19}$" 9 | ConstraintDescription: Between 4-20 letters and digits, starting with a letter 10 | ParameterVPCId: 11 | Description: ID of the VPC 12 | Type: AWS::EC2::VPC::Id 13 | ParameterSubnetId: 14 | Description: SubnetId, for Availability Zone 1 in the region in your VPC. 15 | Type: AWS::EC2::Subnet::Id 16 | ParameterAZ: 17 | Type: String 18 | LatestAmiId: 19 | Type: 'AWS::SSM::Parameter::Value' 20 | Default: '/aws/service/storagegateway/ami/FILE_S3/latest' 21 | InstanceType: 22 | Description: EC2 instance type 23 | Type: String 24 | Default: m5.xlarge 25 | AllowedValues: [ 26 | c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, 27 | c5.large, c5.xlarge, c5.2xlarge, c5.4xlarge, c5.9xlarge, c5.12xlarge, c5.18xlarge, 28 | i3.xlarge, i3.2xlarge, i3.4xlarge, i3.8xlarge, i3.16xlarge, 29 | m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, m4.16xlarge, 30 | m5.xlarge, m5.2xlarge, m5.4xlarge, m5.8xlarge, m5.12xlarge, m5.16xlarge, m5.24xlarge, m5.metal, 31 | r3.xlarge, r3.2xlarge, r3.4xlarge, r3.8xlarge, r3.16xlarge 32 | ] 33 | ConstraintDescription: Please choose a valid instance type. 34 | EBSVolumeSize: 35 | Type: Number 36 | Default: 150 37 | Description: The Amazon EBS volume size attached to the File Gateway as cache, in GiBs. 38 | FileGatewayBucketName: 39 | Type: String 40 | Description: The S3 bucket name for s3 file gateway 41 | 42 | Resources: 43 | FileGatewayBucket: 44 | Type: AWS::S3::Bucket 45 | Properties: 46 | BucketName: !Join 47 | - '-' 48 | - - !Ref FileGatewayBucketName 49 | - !Ref AWS::AccountId 50 | - !Ref AWS::Region 51 | BucketEncryption: 52 | ServerSideEncryptionConfiguration: 53 | - ServerSideEncryptionByDefault: 54 | SSEAlgorithm: AES256 55 | VersioningConfiguration: 56 | Status: Enabled 57 | 58 | InstanceSecurityGroup: 59 | Type: AWS::EC2::SecurityGroup 60 | Properties: 61 | GroupDescription: Enable SSH access via port 22 62 | GroupName: !Sub ${Namespace}-InstanceSecurityGroup-${AWS::AccountId}-${AWS::Region} 63 | SecurityGroupIngress: 64 | - CidrIp: '0.0.0.0/0' 65 | Description: web:80/tcp 66 | FromPort: 80 67 | IpProtocol: TCP 68 | ToPort: 80 69 | - CidrIp: '0.0.0.0/0' 70 | Description: efs:2049/tcp 71 | FromPort: 2049 72 | IpProtocol: TCP 73 | ToPort: 2049 74 | SecurityGroupEgress: 75 | - CidrIp: 0.0.0.0/0 76 | IpProtocol: "-1" 77 | Tags: 78 | - Key: project 79 | Value: !Sub "${Namespace}-sg" 80 | VpcId: !Ref 'ParameterVPCId' 81 | 82 | EC2S3FileGateway: 83 | Type: AWS::EC2::Instance 84 | Properties: 85 | ImageId: !Ref LatestAmiId 86 | AvailabilityZone: !Ref ParameterAZ 87 | SecurityGroupIds: 88 | - !Ref 'InstanceSecurityGroup' 89 | SubnetId: !Ref ParameterSubnetId 90 | InstanceType: !Ref 'InstanceType' 91 | BlockDeviceMappings: 92 | - DeviceName: /dev/sdb 93 | Ebs: 94 | VolumeSize: !Ref EBSVolumeSize 95 | VolumeType: "gp2" 96 | DeleteOnTermination: true 97 | IamInstanceProfile: !Ref 'EC2InstanceProfile' 98 | EC2Role: 99 | Type: AWS::IAM::Role 100 | Properties: 101 | AssumeRolePolicyDocument: 102 | Statement: 103 | - Effect: Allow 104 | Principal: 105 | Service: 106 | - ec2.amazonaws.com 107 | Action: 108 | - sts:AssumeRole 109 | Path: / 110 | ManagedPolicyArns: 111 | - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 112 | EC2InstanceProfile: 113 | Type: AWS::IAM::InstanceProfile 114 | Properties: 115 | Path: / 116 | Roles: 117 | - !Ref 'EC2Role' 118 | 119 | 120 | -------------------------------------------------------------------------------- /OMERO-cloudformation-templates/omero_ec2_uploader_template.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: '2010-09-09' 2 | 3 | Parameters: 4 | VPCID: 5 | Description: ID of the VPC 6 | Type: AWS::EC2::VPC::Id 7 | PrivateSubnetId: 8 | Description: SubnetId, for Availability Zone 1 in the region in your VPC 9 | Type: AWS::EC2::Subnet::Id 10 | OmeroSecurityGroup: 11 | Description: Security group for OMERO web and service containers 12 | Type: AWS::EC2::SecurityGroup::Id 13 | InstanceType: 14 | Description: EC2 instance type. OPTIONAL only for EC2 launch type. 15 | Type: String 16 | Default: m4.large 17 | AllowedValues: [t2.large, m3.large, 18 | m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, 19 | c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, c3.large, c3.xlarge, 20 | c3.2xlarge, c3.4xlarge, c3.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, 21 | r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge] 22 | ConstraintDescription: Please choose a valid instance type. 23 | NumberofEC2Instances: 24 | Description: Number of EC2 instance to run container in ECS cluster. OPTIONAL only for EC2 lanuch type. 25 | Type: Number 26 | Default: 1 27 | EFSSecurityGroup: 28 | Description: Security group for EFS 29 | Type: AWS::EC2::SecurityGroup::Id 30 | EFSFileSystem: 31 | Description: The ID of the EFS volume 32 | Type: String 33 | AccessPoint: 34 | Description: The Access Point of the EFS volume 35 | Type: String 36 | MountPoint: 37 | Description: The Linux mount point for the EFS volume 38 | Type: String 39 | MinLength: '1' 40 | Default: myEFSvolume 41 | 42 | Mappings: 43 | AWSRegionToAMI: 44 | us-east-1: 45 | AMIID: ami-0c1f575380708aa63 46 | us-east-2: 47 | AMIID: ami-015a2afe7e1a8af56 48 | us-west-1: 49 | AMIID: ami-032a827d612b78a50 50 | us-west-2: 51 | AMIID: ami-05edb14e89a5b98f3 52 | ap-northeast-1: 53 | AMIID: ami-06ee72c3360fd7fad 54 | ap-northeast-2: 55 | AMIID: ami-0cfc5eb79eceeeec9 56 | ap-south-1: 57 | AMIID: ami-078902ae8103daac8 58 | ap-southeast-1: 59 | AMIID: ami-09dd721a797640468 60 | ap-southeast-2: 61 | AMIID: ami-040bd2e2325535b3d 62 | ca-central-1: 63 | AMIID: ami-0a06b44c462364156 64 | eu-central-1: 65 | AMIID: ami-09509e8f8dea8ab83 66 | eu-north-1: 67 | AMIID: ami-015b157d082fd4e0d 68 | eu-west-1: 69 | AMIID: ami-0489c3efb4fe85f5d 70 | eu-west-2: 71 | AMIID: ami-037dd70536680c11f 72 | eu-west-3: 73 | AMIID: ami-0182381900083ba64 74 | sa-east-1: 75 | AMIID: ami-05313c3a9e9148109 76 | 77 | Resources: 78 | 79 | MountTarget: 80 | Type: AWS::EFS::MountTarget 81 | Properties: 82 | FileSystemId: !Ref EFSFileSystem 83 | SubnetId: !Ref PrivateSubnetId 84 | SecurityGroups: 85 | - !Ref EFSSecurityGroup 86 | 87 | AutoScalingGroup: 88 | Type: AWS::AutoScaling::AutoScalingGroup 89 | Properties: 90 | VPCZoneIdentifier: 91 | - !Ref PrivateSubnetId 92 | LaunchConfigurationName: !Ref 'LaunchConfiguration' 93 | MinSize: '1' 94 | MaxSize: '2' 95 | DesiredCapacity: !Ref NumberofEC2Instances 96 | CreationPolicy: 97 | ResourceSignal: 98 | Timeout: PT15M 99 | UpdatePolicy: 100 | AutoScalingReplacingUpdate: 101 | WillReplace: 'true' 102 | LaunchConfiguration: 103 | Type: AWS::AutoScaling::LaunchConfiguration 104 | Metadata: 105 | AWS::CloudFormation::Init: 106 | configSets: 107 | MountConfig: 108 | - setup 109 | - mount 110 | setup: 111 | packages: 112 | yum: 113 | nfs-utils: [] 114 | files: 115 | "/home/ec2-user/post_nfsstat": 116 | content: !Sub | 117 | #!/bin/bash 118 | 119 | INPUT="$(cat)" 120 | CW_JSON_OPEN='{ "Namespace": "EFS", "MetricData": [ ' 121 | CW_JSON_CLOSE=' ] }' 122 | CW_JSON_METRIC='' 123 | METRIC_COUNTER=0 124 | 125 | for COL in 1 2 3 4 5 6; do 126 | 127 | COUNTER=0 128 | METRIC_FIELD=$COL 129 | DATA_FIELD=$(($COL+($COL-1))) 130 | 131 | while read line; do 132 | if [[ COUNTER -gt 0 ]]; then 133 | 134 | LINE=`echo $line | tr -s ' ' ` 135 | AWS_COMMAND="aws cloudwatch put-metric-data --region ${AWS::Region}" 136 | MOD=$(( $COUNTER % 2)) 137 | 138 | if [ $MOD -eq 1 ]; then 139 | METRIC_NAME=`echo $LINE | cut -d ' ' -f $METRIC_FIELD` 140 | else 141 | METRIC_VALUE=`echo $LINE | cut -d ' ' -f $DATA_FIELD` 142 | fi 143 | 144 | if [[ -n "$METRIC_NAME" && -n "$METRIC_VALUE" ]]; then 145 | INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) 146 | CW_JSON_METRIC="$CW_JSON_METRIC { \"MetricName\": \"$METRIC_NAME\", \"Dimensions\": [{\"Name\": \"InstanceId\", \"Value\": \"$INSTANCE_ID\"} ], \"Value\": $METRIC_VALUE }," 147 | unset METRIC_NAME 148 | unset METRIC_VALUE 149 | 150 | METRIC_COUNTER=$((METRIC_COUNTER+1)) 151 | if [ $METRIC_COUNTER -eq 20 ]; then 152 | # 20 is max metric collection size, so we have to submit here 153 | aws cloudwatch put-metric-data --region ${AWS::Region} --cli-input-json "`echo $CW_JSON_OPEN ${!CW_JSON_METRIC%?} $CW_JSON_CLOSE`" 154 | 155 | # reset 156 | METRIC_COUNTER=0 157 | CW_JSON_METRIC='' 158 | fi 159 | fi 160 | 161 | COUNTER=$((COUNTER+1)) 162 | fi 163 | 164 | if [[ "$line" == "Client nfs v4:" ]]; then 165 | # the next line is the good stuff 166 | COUNTER=$((COUNTER+1)) 167 | fi 168 | done <<< "$INPUT" 169 | done 170 | 171 | # submit whatever is left 172 | aws cloudwatch put-metric-data --region ${AWS::Region} --cli-input-json "`echo $CW_JSON_OPEN ${!CW_JSON_METRIC%?} $CW_JSON_CLOSE`" 173 | mode: '000755' 174 | owner: ec2-user 175 | group: ec2-user 176 | "/home/ec2-user/crontab": 177 | content: "* * * * * /usr/sbin/nfsstat | /home/ec2-user/post_nfsstat\n" 178 | owner: ec2-user 179 | group: ec2-user 180 | commands: 181 | 01_createdir: 182 | command: !Sub "mkdir /${MountPoint}" 183 | mount: 184 | commands: 185 | 01_mount: 186 | command: !Sub > 187 | mount -t efs -o tls,accesspoint=${AccessPoint} ${EFSFileSystem}.efs.${AWS::Region}.amazonaws.com:/ /${MountPoint} 188 | 02_permissions: 189 | command: !Sub "chown ec2-user:ec2-user /${MountPoint}" 190 | Properties: 191 | ImageId: !FindInMap [AWSRegionToAMI, !Ref 'AWS::Region', AMIID] 192 | SecurityGroups: 193 | - !Ref OmeroSecurityGroup 194 | InstanceType: !Ref 'InstanceType' 195 | IamInstanceProfile: !Ref 'EC2InstanceProfile' 196 | UserData: 197 | Fn::Base64: !Sub | 198 | #!/bin/bash -xe 199 | yum install -y aws-cfn-bootstrap bzip2 unzip 200 | curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 201 | unzip awscliv2.zip 202 | ./aws/install 203 | /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfiguration --configsets MountConfig --region ${AWS::Region} 204 | crontab /home/ec2-user/crontab 205 | /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource AutoScalingGroup --region ${AWS::Region} 206 | yum install java-11-amazon-corretto-headless -y 207 | curl -LO https://anaconda.org/anaconda-adam/adam-installer/4.4.0/download/adam-installer-4.4.0-Linux-x86_64.sh 208 | bash adam-installer-4.4.0-Linux-x86_64.sh -b -p /opt/adam 209 | echo -e '\n# Anaconda Adam\nexport PATH=/opt/adam/bin:$PATH' >> /etc/bashrc 210 | source /etc/bashrc 211 | conda install -c anaconda libstdcxx-ng -y 212 | conda install -c anaconda libgcc-ng -y 213 | EC2Role: 214 | Type: AWS::IAM::Role 215 | Properties: 216 | AssumeRolePolicyDocument: 217 | Statement: 218 | - Effect: Allow 219 | Principal: 220 | Service: 221 | - ec2.amazonaws.com 222 | Action: 223 | - sts:AssumeRole 224 | Path: / 225 | ManagedPolicyArns: 226 | - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role 227 | - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 228 | - arn:aws:iam::aws:policy/AmazonS3FullAccess 229 | - arn:aws:iam::aws:policy/CloudWatchFullAccess 230 | Tags: 231 | - Key: project 232 | Value: omero-on-aws 233 | - Key: service 234 | Value: omeroloader 235 | EC2InstanceProfile: 236 | Type: AWS::IAM::InstanceProfile 237 | Properties: 238 | Path: / 239 | Roles: [!Ref 'EC2Role'] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Digital Pathology on AWS 2 | 3 | ## Contents 4 | 5 | * [OMERO on AWS](#omero-on-aws) 6 | * [Overview](#overview) 7 | * [OMERO Stack Deployment Options](#deployment-options-for-omero-stack) 8 | * [OMERO Core Stack Cost Estimate](#omero-core-stack-cost-estimate) 9 | * [OMERO Data Ingestion Options](#omero-data-ingestion-options) 10 | * [Transfer Image Data into EFS](#transfer-image-data-into-efs) 11 | * [Transfer Image Data using Storage Gateway](#transfer-image-data-using-storage-gateway) 12 | * [Cost Estimate for Storage](#cost-estimate-for-storage) 13 | * [Amazon S3 File Gateway Deployment](#amazon-s3-file-gateway-deployment) 14 | * [Deployment Architecture with only RW Omero Server on EC2, leveraging Amazon S3 File Gateway](#deployment-architecture-with-only-rw-omero-server-on-ec2-leveraging-amazon-s3-file-gateway) 15 | * [Run Amazon ECS Exec Command to Import Images](#run-amazon-ecs-exec-command-to-import-images) 16 | * [Automated File Import using OMERO DropBox on ECS/EC2](#automated-file-import-using-omero-dropbox-on-ecs/ec2) 17 | * [OMERO insight on AppStream](#omero-insight-on-appstream) 18 | * [OMERO CLI on EC2](#omero-cli-on-ec2) 19 | * [OMERO Server Container Application Logs in CloudWatch](#omero-server-container-application-logs-in-cloudwatch) 20 | * [OMERO Application Monitoring Dashboard in CloudWatch](#omero-application-monitoring-dashboard-in-cloudwatch) 21 | * [Clean Up the deployed stack](#clean-up) 22 | * [Reference](#reference) 23 | * [Security](#security) 24 | * [License](#license) 25 | * [Disclaimer](#disclaimer) 26 | 27 | ----- 28 | ## OMERO on AWS 29 | 30 | [OMERO](https://www.openmicroscopy.org/omero/) is an open source microscopic image management tool. [OMERO deployment](https://github.com/ome/omero-deployment-examples) is a typical three tier Web application. OMERO web and server are containerized and can run on [AWS ECS](https://aws.amazon.com/ecs). The data is stored in the [AWS EFS](https://aws.amazon.com/efs/) mounted to OMERO server and the [AWS RDS](https://aws.amazon.com/rds/) PostgreSQL database. [Amazon EFS Intelligent-tiering](https://aws.amazon.com/blogs/aws/new-amazon-efs-intelligent-tiering-optimizes-costs-for-workloads-with-changing-access-patterns/) can reduce the storage cost for workloads with changing access patterns. 31 | 32 | ----- 33 | ## Overview 34 | 35 | First create the network infrastructure. One way to do it is to deploy using [this CloudFormation template](https://docs.aws.amazon.com/codebuild/latest/userguide/cloudformation-vpc-template.html), which will create one [AWS VPC](https://aws.amazon.com/vpc/), two public subnets and two private subnets. If you want to add [VPC flow logs](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html), you can deploy [the network infrastructure CloudFormation template](https://github.com/aws-samples/digital-pathology-on-aws/blob/main/OMERO-cloudformation-templates/OMERONetworkInfra.yaml) in this repository and select true for AddVPCFlowLog parameter. 36 | 37 | If you have registered or transfer your domain to AWS Route53, you can use the associated Hosted zones to [automate the DNS validatition for the SSL certificate](https://aws.amazon.com/blogs/security/how-to-use-aws-certificate-manager-with-aws-cloudformation/) issued by [AWS Certificate Manager (ACM)](https://aws.amazon.com/certificate-manager/). It is noteworthy the Route53 domain and associated public Hosted zone should be on the same AWS account as the ACM that issues SSL certificate, in order to automate the DNS validation. ACM will create a validation CNAME record in the public Hosted zone. This DNS validated public certificate can be used for [TLS termination for Applicaton Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html) 38 | 39 | ----- 40 | 41 | ## Deployment Architecture 42 | ![arch](Figures/omero-on-aws-ha.jpg) 43 | 44 | ----- 45 | ## Deployment options for OMERO Stack 46 | 47 | 1. Quick Start - **Deployment Architecture with RW and RO Omero Server** 48 | - Current OMERO server only support one writer per mounted network share file. To avoid a race condition between the two instances trying to own a lock on the network file share, we will deploy one read+write OMERO server and one read only OMERO server. 49 | - Stack will deploy two nested CloudFormation templates, one for storage (EFS and RDS) and one for ECS containers (OMERO web and server). It also deploys a certificate for TLS termination at Application Load Balancer. Majority of parameters already have default values filled and subject to be customized. VPC and Subnets are required, which can be obtained from pre-requisite deployment. It also requires the Hosted Zone ID and fully qualifed domain name in [AWS Route53](https://aws.amazon.com/route53/), which will be used to validate SSL Certificate issued by [AWS ACM](https://aws.amazon.com/certificate-manager/). 50 | - Choose Launch Stack and (if prompted) log into your AWS account: 51 | 52 | [![launchstackbutton](Figures/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/template?stackName=omerostack&templateURL=https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROstackTLS_RW_RO.yml) 53 | 54 | 2. Quick Start - **Deployment Architecture with only RW Omero Server** 55 | - If you do not need the redundency for read only OMERO server, you can deploy a single read+write OMERO server. 56 | - Choose Launch Stack and (if prompted) log into your AWS account: 57 | 58 | [![launchstackbutton](Figures/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/template?stackName=omerostack&templateURL=https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROstackTLS_RW.yml) 59 | 60 | - Note: Even though the OMERO server is deployed in single instance, you can achieve the Hight Availability (HA) deployment of OMERO web and PostgreSQL database. You have option to deploy the OMERO containers on ECS Fargate or EC2 launch type. 61 | 62 | 63 | 3. **Deployment Architecture with only RW Omero Server with ingress access** 64 | - If you want to expose the OMERO server port, i.e. 4064 and 4063, to public, you can deploy a stack with [Network Load Balancer (NLB)](https://aws.amazon.com/elasticloadbalancing/network-load-balancer/) for those two ports 65 | - Choose Launch Stack and (if prompted) log into your AWS account: 66 | 67 | [![launchstackbutton](Figures/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/template?stackName=omerostack&templateURL=https://omero-on-aws.s3.us-west-1.amazonaws.com/OMERO2LBstackTLS_RW.yml) 68 | 69 | 4. **Deployment Architecture with only RW Omero Server without hosted zone in AWS** 70 | - If you do not have registered domain and associated hosted zone in AWS Route53, you can deploy the following CloudFormation stacks and access to OMERO web through Application Load Balancer DNS name without TLS termination. 71 | - Choose Launch Stack and (if prompted) log into your AWS account: 72 | 73 | [![launchstackbutton](Figures/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/template?stackName=omerostack&templateURL=https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROstack_RW.yml) 74 | 75 | ---- 76 | 77 | ## Omero Core Stack Cost Estimate 78 | 79 | - A cost estimate for the compute resources deployed by this solution can be found [here](https://calculator.aws/#/estimate?id=15abc33f2c524886f08547f2f48e66dee7112955). 80 | 81 | ---- 82 | 83 | ## OMERO Data Ingestion Options 84 | 85 | There are multiple ways to ingest image data into OMERO on AWS: 86 | 1. Transfer data directly to EFS mounted to OMERO server through [AWS Transfer Family](https://aws.amazon.com/aws-transfer-family/), from on premises data center or data acquisition facilities. 87 | 2. Transfer data to EFS through [AWS DataSync](https://aws.amazon.com/datasync/), either from on premises data acquisition or from [Amazon S3](https://aws.amazon.com/s3/). 88 | 3. Upload data to [Amazon S3](https://aws.amazon.com/s3/) first through [AWS Stroage Gateway](https://aws.amazon.com/storagegateway/) or other tools, then import into OMERO using virtualized [OMERO.insight](https://github.com/ome/omero-insight) desktop application accessed through [Amazon AppStream 2.0](https://aws.amazon.com/appstream2) 89 | 90 | ---- 91 | 92 | ## Transfer Image Data into EFS 93 | 94 | There are [two primary ways to land image data into EFS file share](https://docs.aws.amazon.com/efs/latest/ug/transfer-data-to-efs.html), using [AWS DataSync](https://docs.aws.amazon.com/efs/latest/ug/gs-step-four-sync-files.html) or [AWS Transfer Family](https://aws.amazon.com/blogs/aws/new-aws-transfer-family-support-for-amazon-elastic-file-system/). 95 | 96 | 1. AWS DataSync can be used to [transfer data from S3](https://aws.amazon.com/premiumsupport/knowledge-center/datasync-transfer-efs-s3/) as well. 97 | 2. You can create a DataSync task to monitor a S3 bucket and copy the files over to the EFS file share mounted to OMERO server using 1-click deployment: 98 | 3. Choose Launch Stack and (if prompted) log into your AWS account: 99 | 100 | [![launchstackbutton](Figures/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/template?stackName=omerodatasyncstack&templateURL=https://omero-on-aws.s3.us-west-1.amazonaws.com/OMERO_DataSync.yaml) 101 | 102 | ---- 103 | 104 | ## Transfer Image Data using Storage Gateway 105 | If you have huge amount of data and I/O performance is not critical, you can save the image files on Amazon S3 and deploy a S3 filegateway on Amazon EC2 to cache a subset of files, and mount a NFS file share instead of Amazon EFS volume to OMERO server. Although Amazon S3 cost significantly less than Amazon EFS, the file gateway instance does have the extra cost. 106 | 107 | 108 | 109 | ---- 110 | ## Cost Estimate for Storage 111 | Review the storage cost comparison for 2TB of data between Amazon EFS with intelligent tiering and Amazon S3 with filegateway on EC2 112 | - [Amazon EFS with intelligent tiering](https://calculator.aws/#/estimate?id=bbaac0d5d38a5c2d457848cae5745cdbbfeddb92) 113 | - [Amazon S3 with filegateway on EC2](https://calculator.aws/#/estimate?id=688458e015f93858a005995d91597775bf67731f) 114 | 115 | ---- 116 | ## Amazon S3 File Gateway Deployment 117 | 118 | You can follow the [instruction to deploy an Amazon S3 File gateway on EC2](https://docs.aws.amazon.com/storagegateway/latest/userguide/ec2-gateway-file.html) to cache the images in S3 bucket to reduce storage cost. Alternatively, you can follow the below steps to deploy and configure Amazon S3 File Gateway. 119 | 120 | 1. Cloudformation template will create a EC2 File Gateway and S3 bucket for storing the images in an S3 Bucket. 121 | 122 | 2. Choose Launch Stack and (if prompted) log into your AWS account: 123 | 124 | [![launchstackbutton](Figures/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/template?stackName=s3filegatewayinstance&templateURL=https://omero-on-aws.s3-us-west-1.amazonaws.com/ec2s3filegateway.yaml) 125 | 126 | 3. Once the stack is deployed you should have an EC2 Instance that you can now use to configure your Amazon S3 File Gateway. Navigate to the [File Gateway](https://us-east-1.console.aws.amazon.com/storagegateway/home?region=us-west-1#/gateways/create) on AWS Console and specify a name and appropriate time zone and select Gateway type of Amazon S3 File Gateway. 127 | 128 | 129 | 130 | 4. Connect to the EC2 file gateway instance through IP address and activate it. Follow [instruction](https://docs.aws.amazon.com/storagegateway/latest/userguide/create-gateway-file.html#GettingStartedBeginActivateGateway-file) to configure local disks and logging. 131 | 132 | 5. Create a [NFS file share](https://docs.aws.amazon.com/storagegateway/latest/userguide/CreatingAnNFSFileShare.html) on top of the S3 bucket created earlier. If you want to upload files to S3 bucket separately and have them visible to the NFS share, you should configure the cache refresh: 133 | 134 | 135 | 136 | 6. If you want to make all of the files uploaded to S3 visible as owned by **omero-server** within container mounted to the storage gateway, you can make the following change to the new file share created: 137 | 138 | 139 | 140 | 7. After storage gateway setup, you can revoke the storage gateway EC2 instance security group ingress rule for port 80, which is only used for storage gateway activation. 141 | 142 | 143 | 144 | 145 | ---- 146 | ## **Deployment Architecture with only RW Omero Server on EC2, leveraging Amazon S3 File Gateway** 147 | 1. Note the two parameters from the S3 File Gateway deployment: **S3FileGatewayIp** and **S3BucketName**. 148 | 2. Deploy OMERO stack with NFS mount as storage backend through this 1-click deployment: 149 | 150 | [![launchstackbutton](Figures/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/template?stackName=omerostack&templateURL=https://omero-on-aws.s3-us-west-1.amazonaws.com/OMEROonECS_RW_S3FG.yml) 151 | 152 | 3. Deploy OMERO stack with NFS mount as storage backend through this 1-click deployment with a domain name and SSL certificate: 153 | 154 | [![launchstackbutton](Figures/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/template?stackName=omerostack&templateURL=https://omero-on-aws.s3.us-west-1.amazonaws.com/OMEROonECS_RW_TLS_S3FG.yml) 155 | 156 | ----- 157 | ## Run Amazon ECS Exec Command to Import Images 158 | 159 | 1. Once image data landed on EFS, you can access and import them into OMERO using Command Line Interface (CLI). [Amazon ECS Exec command has been enabled](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html) for OMERO.server container service. 160 | 2. Note: To run ECS Exec command on Fargate containers, you should have AWS CLI v1.19.28/v2.1.30 or later installed first, and install [SSM plugin for AWS CLI](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html). 161 | 2. Setup steps: 162 | 163 | - Grab your ECS task ID of OMERO server on AWS ECS Console, and run: 164 | 165 | ```bash 166 | aws ecs execute-command --cluster OMEROECSCluster --task --interactive --command "/bin/sh" 167 | ``` 168 | 169 | - If you failed to execute the command, you can use the [diagnosis tool](https://github.com/aws-containers/amazon-ecs-exec-checker) to check the issue. 170 | 171 | - After login, you will need to change to a non-root OMERO system user, like `omero-server`, and activate the virtual env: 172 | 173 | ```bash 174 | source /opt/omero/server/venv3/bin/activate 175 | ``` 176 | 177 | - After environment activated, you can run [in-place import](https://docs.openmicroscopy.org/omero/5.6.1/sysadmins/in-place-import.html) on images that have already been transfered to the EFS mount, like `omero import --transfer=ln_s `. It is noteworthy that the [OMERO CLI importer](https://omero-guides.readthedocs.io/en/latest/upload/docs/import-cli.html#in-place-import-using-the-cli) has to run on the OMERO server container. 178 | 179 | - **If you deployed OMERO server on EC2 launch type**, you can run docker commands to import images as well. Assuming you want to import all of the images in `/OMERO/downloads`: 180 | 181 | ```bash 182 | containerID=`docker ps | grep omeroserver | awk '{print $1;}'` 183 | files=`docker exec $containerID bash -c "ls /OMERO/downloads"` 184 | for FILE in $files; do docker exec $containerID bash -c "source /opt/omero/server/venv3/bin/activate; omero import -s localhost -p 4064 -u root --transfer=ln_s /OMERO/downloads/$FILE"; done 185 | ``` 186 | 187 | ---- 188 | ## Automated File Import using OMERO DropBox on ECS/EC2 189 | 190 | OMERO supports automated file import using [DropBox](https://omero-guides.readthedocs.io/en/latest/upload/docs/import-dropbox.html). OMERO.dropbox allows to import files into OMERO automatically, by means of offline import from a watched directory. 191 | 192 | 1. Assuming that you have already exec into the omero-server container. 193 | 2. You can create a folder in the `/OMERO/DropBox` directory with folder name as username, like: 194 | ```bash 195 | mkdir /OMERO/DropBox/root 196 | ``` 197 | 198 | 3. Then run the following commands to create the automated import job on OMERO server: 199 | ```bash 200 | export OMERODIR=/opt/omero/server/OMERO.server 201 | $OMERODIR/bin/omero config set omero.fs.watchDir "/OMERO/DropBox" 202 | $OMERODIR/bin/omero config set omero.fs.importArgs '-T "regex:^.*/(?.*?)"' 203 | ``` 204 | 205 | 4. You can check if jobs are created successfully, by checking `/opt/omero/server/OMERO.server/var/log/DropBox.log` file, you should see something like: `Started OMERO.fs DropBox client` 206 | 207 | 5. According to the [documentation](https://docs.openmicroscopy.org/omero/5.6.3/sysadmins/dropbox.html), you can add different arguments, like for in-place import: 208 | ```bash 209 | $OMERODIR/bin/omero config set omero.fs.importArgs '-T "regex:^.*/(?.*?)"; --transfer=ln_s' 210 | ``` 211 | or to check if a given path has already been imported beforehand (avoid duplicate import): 212 | ```bash 213 | $OMERODIR/bin/omero config set omero.fs.importArgs '-T "regex:^.*/(?.*?)"; --exclude=clientpath' 214 | ``` 215 | 216 | ---- 217 | ## OMERO insight on AppStream 218 | 219 | Here are steps to run [OMERO.insight](https://docs.openmicroscopy.org/omero/5.6.1/users/clients-overview.html#omero-insight) on Amazon AppStream 2.0, which can import data from Amazon S3 directly into OMERO server: 220 | 221 | 1. Follow [instruction](https://docs.aws.amazon.com/appstream2/latest/developerguide/tutorial-image-builder.html) to create a custom image using AppStream console. The Windows installation file can be [downloaded here](https://www.openmicroscopy.org/omero/downloads/). Launch image builder and start with any of the Windows base images, select size of instance, either create a new or use existing IAM role with S3 access permission. Select the VPC where OMERO stack was deployed, and a public subnet that can be access through internet. The image builder instance will be stopped after image building. 222 | 223 | 224 | 225 | Once image is successfully created, you will find it in Image Registry: 226 | 227 | 228 | 229 | 2. Follow [instructions](https://docs.aws.amazon.com/appstream2/latest/developerguide/set-up-stacks-fleets.html) to create a fleet and a stack. When you create the fleet, select the VPC where OMERO stack was deployed, two public subnets that can be access through internet, and OMERO security group that allow access to OMERO server. 230 | 231 | 232 | 233 | When you create the stack, [enable the Home Folder in Amazon S3](https://docs.aws.amazon.com/appstream2/latest/developerguide/home-folders.html), then you will be able to import image files from S3 directly to OMERO server. 234 | 235 | 236 | 237 | 3. Create a user in the AppStream 2.0 User Pool, and access OMERO.insight through the streaming service using the login URL in the email or created for the given stack. Once access the virtualized OMERO.insight on AppStream 2.0, you can access the home folder on S3 and setup OMERO server connection. 238 | 239 | 240 | 241 | The OMERO server container instance has been assigned with a private IP address by [awsvpc network model](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-networking.html) in this deployment. The IP address can be found on AWS console ECS Cluster => Task => Task detail page: 242 | 243 | 244 | 245 | 246 | 247 | 248 | ---- 249 | ## OMERO CLI on EC2 250 | 251 | **It is noteworthy that the OMERO CLI cannot perform in-place import on separate EC2 instance.** 252 | 253 | 1. If you want to run OMERO CLI client on another EC2 instance to transfer and import images from [Amazon S3](https://aws.amazon.com/s3/), you can use this 1-click deployment: 254 | 255 | [![launchstackbutton](Figures/launchstack.png)](https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/template?stackName=omeroec2loader&templateURL=https://omero-on-aws.s3-us-west-1.amazonaws.com/omero_ec2_uploader_template.yaml) 256 | 257 | 2. You can reuse the EFSFileSystem Id, AccessPoint Id, EFSSecurityGroup, OmeroSecurityGroup, PrivateSubnetId, and VPCID from the aforementioned deployments. EC2 instance have installed [AWS CLI](https://aws.amazon.com/cli/), [Amazon Corretto 11](https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/what-is-corretto-11.html), and [omero-py](https://docs.openmicroscopy.org/omero/5.6.0/developers/Python.html), using [AWS EC2 user data shell scripts](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html). To import microscopic images to OMERO server, you can connect to the EC2 instance using Session Manager (login as ssm-user) and run: 258 | 259 | ```bash 260 | source /etc/bashrc 261 | conda create -n myenv -c ome python=3.6 bzip2 expat libstdcxx-ng openssl libgcc zeroc-ice36-python omero-py -y 262 | source activate myenv 263 | ``` 264 | 265 | 3. You can download image from AWS S3 using command: 266 | ```bash 267 | aws s3 cp s3://xxxxxxxx.svs . 268 | ``` 269 | 270 | and then use [OMERO client CLI](https://docs.openmicroscopy.org/omero/5.6.1/users/cli/index.html) on the EC2 instance to [import the image to OMERO](https://docs.openmicroscopy.org/omero/5.4.8/users/cli/import.html): 271 | 272 | ```bash 273 | omero login 274 | ``` 275 | 276 | 4. The IP address of the OMERO server can be found in the same way demonstrated above. The default port number is 4064, and default username (root) and password (omero) for OMERO are used here. Once you login, you can import whole slide images, like: 277 | 278 | `omero import ./xxxxxx.svs` 279 | 280 | ---- 281 | ## OMERO Server Container Application Logs in CloudWatch 282 | 283 | Note: **Option valid for ECS/EC2 deployment only**. 284 | 285 | Omero server container has multiple applications running that generate logs that are not streamed to STDOUT and STDERR I/O streams and are a result not available on CloudWatch. Reviewing the application logs from within the container is not ideal since this would require manual steps and prevent being reactive to events in application log. 286 | 287 | In order to limit changes to the Omero Server opensource code and change the default log4j configurations and to also support easier path to upgrade and maintenance, one of the options is to make the application logs from the container available on EC2 and use [CloudWatch Log Agent](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html) to send these logs to CloudWatch that can persist beyond the life of the container and also provide better observability into the Omero Server container application. 288 | 289 | CFN template automates the deployment of the CloudWatch log configuration for omero server. Steps involved for the automation are the following: 290 | 1. Omero server logs from the container are mounted to the host on the `/var/log/omero` directory with appropriate permissions. Please modify the permissions based on your organization's best practices. 291 | 2. CloudWatch log agent configuration provides the default log files to be monitored and the configuration is stored in SSM parameter store. Please update the configuration based on the additional log files that you want to ingest into CloudWatch. Additional CloudWatch Log Agent configuration options are described [here](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-common-scenarios.html) 292 | 3. Omero server task definition is configured for the bind mount and associated volume mapping to the container. 293 | 4. Once the task is running you should start seeing the logs on CloudWatch. 294 | 295 | Omero Server Logs in CloudWatch. 296 | 297 | 298 | 299 | Omero Server Blitz Log in CloudWatch by EC2 Instance. 300 | 301 | 302 | 303 | ---- 304 | ## OMERO Application Monitoring Dashboard in CloudWatch 305 | Omero Application Dashboard is deployed as part of the application deployment. The monitoring dashboard will vary depending on the ECS deployment that is chosen. If you do choose the deploy the Omero Server Container on ECS/EC2 the dashboard will include EC2 metrics in addition to the ALB, Database, ECS Cluster and Container Insights metrics. If you do want to extend the metrics captured in the dashboard please review the `OMEROonECS_Monitoring.yaml` templates for additional customization including any alarm configurations. 306 | 307 | Sample OMERO Application Dashboard available on CloudWatch. 308 | 309 | 310 | 311 | ---- 312 | ## Clean Up 313 | 314 | 1. If you deployed with SSL certificate, go to the HostedZone in Route53 and remove the validation record that route traffic to _xxxxxxxx.xxxxxxxx.acm-validations.aws. 315 | 2. Empty and delete the S3 bucket for Load Balancer access log (LBAccessLogBucket in the template) before deleting the OMERO stack 316 | 3. Manually delete the EFS file system and RDS database. By default the storage retain after the CloudFormation stack is deleted. 317 | 318 | ---- 319 | ## Reference 320 | 321 | The following information was used to build this solution: 322 | 1. [OMERO Docker](https://github.com/ome/docker-example-omero) 323 | 2. [OMERO deployment examples](https://github.com/ome/omero-deployment-examples) 324 | 3. [Deploying Docker containers on ECS](https://docs.docker.com/cloud/ecs-integration/) 325 | 4. [Tutorial on EFS for ECS EC2 launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/tutorial-efs-volumes.html) 326 | 5. [Blog post on EFS for ECS Fargate](https://aws.amazon.com/blogs/aws/amazon-ecs-supports-efs/) 327 | 6. [Blog post on EFS as Docker volume](https://aws.amazon.com/blogs/compute/amazon-ecs-and-docker-volume-drivers-amazon-ebs/) 328 | 329 | 330 | ---- 331 | ## Security 332 | 333 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 334 | 335 | ---- 336 | ## License 337 | 338 | This library is licensed under the MIT-0 License. See the LICENSE file. 339 | 340 | ---- 341 | ## Disclaimer 342 | 343 | This deployment was built based on the [open source version of OMERO](https://www.openmicroscopy.org/licensing/). OMERO is licensed under the terms of the GNU General Public License (GPL) v2 or later. Please note that by running Orthanc under GPLv2, you consent to complying with any and all requirements imposed by GPLv2 in full, including but not limited to attribution requirements. You can see a full list of requirements under [GPLv2](https://opensource.org/licenses/gpl-2.0.php). -------------------------------------------------------------------------------- /custom-docker-container/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Build Customer Container Image with Plugins 3 | 4 | You can build customized container images for [OMERO.web](https://github.com/ome/omero-web-docker) and [OMERO.server](https://github.com/ome/omero-server-docker) by running the script: 5 | 6 | `sh build_and_push.sh ` 7 | 8 | It will build the docker image and upload it to [AWS ECR](https://aws.amazon.com/ecr/). Take a note of the image URL after uploading: 9 | 10 | 11 | 12 | and fill it in the CloudFormation deployment parameters: OMEROWebContainerImageParam or OMEROServerContainerImageParam 13 | 14 | 15 | ### Disclaimer 16 | 17 | The containers were built from the [open source version of OMERO](https://github.com/ome/omero-web-docker). OMERO plugins are licensed under the terms of the GNU General Public License (GPL) v2 or later. Please note that by running Orthanc under GPLv2, you consent to complying with any and all requirements imposed by GPLv2 in full, including but not limited to attribution requirements. You can see a full list of requirements under [GPLv2](https://opensource.org/licenses/gpl-2.0.php). 18 | -------------------------------------------------------------------------------- /custom-docker-container/omero-server/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PARENT_IMAGE=openmicroscopy/omero-server:latest 2 | FROM ${PARENT_IMAGE} 3 | 4 | USER root 5 | 6 | Add Figure_To_Pdf.py /opt/omero/server/OMERO.server/lib/scripts/omero/figure_scripts 7 | 8 | RUN /opt/omero/server/venv3/bin/pip install \ 9 | omero-cli-duplicate \ 10 | omero-metadata \ 11 | omero-cli-render \ 12 | reportlab \ 13 | markdown 14 | 15 | USER omero-server 16 | -------------------------------------------------------------------------------- /custom-docker-container/omero-server/playbook.yml: -------------------------------------------------------------------------------- 1 | - hosts: localhost 2 | roles: 3 | - role: ome.omero_server 4 | omero_server_python_addons: 5 | - "omero-cli-duplicate=={{ omero_cli_duplicate_release }}" 6 | - "omero-cli-render=={{ omero_cli_render_release }}" 7 | - "omero-metadata=={{ omero_metadata_release }}" 8 | - reportlab 9 | - markdown 10 | - scipy 11 | # For "simple frap with figure" script 12 | - matplotlib 13 | tasks: 14 | - name: Add operating system user "importer1" 15 | become: true 16 | user: 17 | name: "importer1" 18 | state: present 19 | groups: "{{ omero_server_system_managedrepo_group }}" 20 | password: "{{ os_system_users_password | password_hash('sha512', 'ome') }}" 21 | vars: 22 | java_versions: ["11"] 23 | omero_server_database_manage: False 24 | omero_server_selfsigned_certificates: True 25 | omero_server_systemd_setup: False 26 | omero_server_system_uid: 1000 27 | omero_server_virtualenv: True 28 | omero_server_python3: True 29 | omero_server_python3_replace_omero: False 30 | postgresql_version: "11" 31 | 32 | omero_server_system_managedrepo_group: managed_repo_group 33 | omero_server_datadir_managedrepo_mode: u=rwX,g=srwX,o=rX,+t 34 | os_system_users_password: "{{ os_system_users_password_override | default('ome') }}" 35 | omero_cli_duplicate_release: "{{ omero_cli_duplicate_release_override | default('0.4.0') }}" 36 | omero_metadata_release: "{{ omero_metadata_release_overrride | default('0.5.0') }}" 37 | omero_cli_render_release: "{{ omero_cli_render_release_override | default('0.6.1') }}" 38 | -------------------------------------------------------------------------------- /custom-docker-container/omero-web/01-default-webapps.omero: -------------------------------------------------------------------------------- 1 | # OMERO.web configuration 2 | 3 | # whitenoise 4 | config append -- omero.web.middleware '{"index": 0, "class": "whitenoise.middleware.WhiteNoiseMiddleware"}' 5 | 6 | # omero-figure 7 | config append -- omero.web.apps '"omero_figure"' 8 | config append -- omero.web.open_with '["omero_figure", "new_figure", {"supported_objects": ["images"], "target": "_blank", "label": "OMERO.figure"}]' 9 | 10 | # omero-iviewer 11 | config append -- omero.web.apps '"omero_iviewer"' 12 | config set -- omero.web.viewer.view omero_iviewer.views.index 13 | config append -- omero.web.open_with '["omero_iviewer", "omero_iviewer_index", {"supported_objects":["images", "dataset", "well"], "script_url": "omero_iviewer/openwith.js", "label": "OMERO.iviewer"}]' 14 | 15 | # omero-mapr 16 | config append -- omero.web.apps '"omero_mapr"' 17 | config append -- omero.web.mapr.config '{"menu": "anyvalue", "config":{"default":["Any Value"], "all":[], "ns":["openmicroscopy.org/omero/client/mapAnnotation"], "label":"Any"}}' 18 | 19 | # omero-parade 20 | config append -- omero.web.apps '"omero_parade"' 21 | config append -- omero.web.ui.center_plugins '["Parade", "omero_parade/init.js.html", "omero_parade"]' 22 | 23 | # omero-fpbioimage 24 | config append -- omero.web.apps '"omero_fpbioimage"' 25 | config append -- omero.web.open_with '["omero_fpbioimage", "fpbioimage_index", {"script_url": "fpbioimage/openwith.js", "supported_objects": ["image"], "label": "FPBioimage"}]' 26 | 27 | 28 | ## set up omero web login index page 29 | #config set omero.web.index_template "custom_login.html" 30 | #config append omero.web.template_dirs '"/opt/omero/web/config"' 31 | #config set omero.web.login_view "webindex_custom" 32 | 33 | # Top links 34 | config set -- omero.web.ui.top_links '[["Data", "webindex", {"title": "Browse Data via Projects, Tags etc"}],["History", "history", {"title": "History"}], ["Mapr", {"viewname": "maprindex_anyvalue"}, {"title": "Find Any Value"}], ["Figure", "figure_index", {"title": "Open Figure in new tab", "target": "_blank"}], ["Help", "https://help.openmicroscopy.org/", {"title":"Open OMERO user guide in a new tab", "target":"new"}]]' 35 | 36 | -------------------------------------------------------------------------------- /custom-docker-container/omero-web/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG PARENT_IMAGE=openmicroscopy/omero-web:latest 2 | FROM ${PARENT_IMAGE} 3 | 4 | USER root 5 | 6 | RUN /opt/omero/web/venv3/bin/pip install \ 7 | 'django-cors-headers<3.3' \ 8 | omero-figure \ 9 | omero-iviewer \ 10 | omero-fpbioimage \ 11 | omero-mapr \ 12 | omero-parade \ 13 | omero-webtagging-autotag \ 14 | omero-webtagging-tagsearch \ 15 | whitenoise \ 16 | omero-fpbioimage 17 | 18 | ADD 01-default-webapps.omero /opt/omero/web/config/ 19 | ADD custom_login.html /opt/omero/web/config/ 20 | 21 | USER omero-web 22 | -------------------------------------------------------------------------------- /custom-docker-container/omero-web/build_and_push.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | profilename=$1 4 | profilename=${profilename:-default} 5 | echo "AWS Profile name is: $profilename" 6 | 7 | # This script shows how to build the Docker image and push it to ECR to be ready for use by SageMaker. 8 | 9 | # The argument to this script is the image name. This will be used as the image on the local 10 | # machine and combined with the account and region to form the repository name for ECR. 11 | image_name=omero-web-plugins 12 | 13 | # Get the account number associated with the current IAM credentials 14 | account=$(aws sts get-caller-identity --query Account --output text --profile $profilename) 15 | 16 | # Get the region defined in the current configuration (default to us-east-1 if none defined) 17 | region=$(aws configure get region --profile $profilename) 18 | region=${region:-us-east-1} 19 | echo "AWS Profile region is: $region" 20 | 21 | 22 | fullname="${account}.dkr.ecr.${region}.amazonaws.com/${image_name}:latest" 23 | echo "ECR image fullname is: $fullname" 24 | 25 | # If the repository doesn't exist in ECR, create it. 26 | aws ecr describe-repositories --repository-names "${image_name}" --profile $profilename > /dev/null 2>&1 27 | 28 | if [ $? -ne 0 ] 29 | then 30 | aws ecr create-repository --repository-name "${image_name}" --profile $profilename > /dev/null 31 | fi 32 | 33 | # Get the login command from ECR and execute it directly 34 | aws ecr get-login-password --region ${region} --profile $profilename | docker login --username AWS --password-stdin ${account}.dkr.ecr.${region}.amazonaws.com 35 | 36 | # Build the docker image locally with the image name and then push it to ECR with the full name. 37 | docker build -t ${image_name} . --build-arg REGION=${region} 38 | docker tag ${image_name} ${fullname} 39 | 40 | docker push ${fullname} --------------------------------------------------------------------------------