Deployment guide

DMPRoadmap 6.0.0

Overview

DMPRoadmap is the open-source data management planning platform behind DMPonline and DMPTool. Researchers write Data Management Plans (DMPs) by answering funder and institutional templates, share them with collaborators, and export them as PDF or Word documents. Administrators manage organizations, templates, guidance and users from the web interface.

This guide covers the DMPRoadmap 6.0.0 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud GIS, health and research applications listing on AWS Marketplace. You pick it as the software version when you subscribe and launch. The image is a hardened, ready-to-use DMPRoadmap server.

What you get:

  • No account and no secret ships in the image. The upstream seed creates four demo accounts that all share the password password123. The build loads the rest of that seed (languages, regions, question formats, identifier schemes, and three example organizations with their templates) and then destroys those accounts, so the image holds no user at all. First boot creates one super administrator with a random password. It also generates this instance's Rails SECRET_KEY_BASE, Devise secret and pepper, upload signing secret and PostgreSQL role password. The PostgreSQL cluster itself is created on first boot, so no two instances share a database system identifier or password. DMPRoadmap's own sample config/credentials.yml, with the project's published placeholder values, is on the image unchanged. DMPRoadmap does not read it, and the running secrets are this instance's.
  • nginx in front, DMPRoadmap behind it. nginx is the only public listener (ports 80 and 443). DMPRoadmap runs in puma on 127.0.0.1:3000 and PostgreSQL 16 on 127.0.0.1:5432, both on the loopback address only. The instance itself refuses 3000 and 5432 from the network.
  • HTTPS from the first boot, with a certificate generated on your instance (an end-entity certificate, not a certificate authority) and TLS 1.2 and 1.3 only. Port 80 redirects to HTTPS, Rails forces SSL and marks its cookies secure, and nginx sends HSTS, a Content Security Policy, Referrer-Policy: same-origin and frame-ancestors 'none'. The instance's name is set from its own address at first boot, and requests for any other host name are dropped. You can change the name to your own domain.
  • Self-registration is closed until you open it. Upstream DMPRoadmap lets anyone who can reach the site create an account and has no switch to stop it. The image adds one (sudo dmproadmap-registration open|close|status). While registration is closed, new users join by administrator invitation.
  • Rate limits on sign-in. Sign-in, password reset and account requests are limited to 10 a minute per client (an IPv4 address or an IPv6 /64), and the application is limited to 20 requests a second. A client cannot move its own limit with a forged X-Forwarded-For header.
  • No mail relay. Nothing listens on port 25, and mail delivery is off until you add your SMTP settings (Step 11).
  • An egress backstop. DMPRoadmap looks up organizations, ORCID identifiers and funders on the internet. To contain that traffic, iptables and systemd refuse the dmproadmap, www-data (nginx) and postgres accounts every connection to the EC2 metadata service, private and carrier-grade NAT addresses, link-local and reserved ranges, and this instance's own VPC ranges, which the instance reads from EC2 metadata at every boot. The backstop is fail closed: if the VPC ranges cannot be read, DMPRoadmap does not start. Public services stay reachable. Step 12 shows how to allow an SMTP relay or identity provider in your VPC on purpose.
  • An unprivileged service. puma runs as the dmproadmap account, which has no shell, no password and no sudo rights. It runs under systemd with NoNewPrivileges, a read-only operating system (ProtectSystem=strict) and core dumps off.
  • Patched, pinned components. DMPRoadmap 6.0.0 is built from the upstream release tarball, checked by SHA-256, on Ruby 3.4.12 compiled from the ruby-lang.org release (also SHA-256). The Ruby gems and JavaScript packages are installed from lockfiles pinned by SHA-256. Within upstream's own version ranges, the build raises Rails, Rack, Nokogiri, Loofah, TinyMCE and a few others to their patched releases. Node.js and Yarn are used only to build the JavaScript and are removed before the image is captured. PostgreSQL 16, nginx and every other package come from the Ubuntu 24.04 main archive, on a fully patched Ubuntu 24.04 LTS with unattended security upgrades on.

What is on the image: DMPRoadmap 6.0.0 (Rails 8.1) on Ruby 3.4.12, puma, PostgreSQL 16, nginx, wkhtmltopdf for PDF export, iptables, cloud-init and the AWS Systems Manager agent.

Default user: ubuntu. Architecture: x86_64. Recommended instance type: m5.large.

Prerequisites

You need:

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet.
  • A security group that allows TCP 22 (SSH), TCP 443 (DMPRoadmap) and TCP 80 (redirects to HTTPS) from the networks your users are on. Do not open 3000 or 5432, because puma and PostgreSQL listen on the loopback address only.
  • IMDSv2 enabled (the default for this AMI). The instance reads its own VPC ranges from the metadata service at every boot. With the metadata service switched off, DMPRoadmap does not start (see Step 12).
  • For production, a DNS name you control (for example dmp.example.com), an SMTP relay for invitations and notifications, and ideally a certificate from a certificate authority. Until then, the instance uses its public IP address with its own self-signed certificate.
1

Launch the instance

In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick DMPRoadmap 6.0.0 on Ubuntu 24.04 as the software version and select your Region, then choose Launch through EC2.

Choose m5.large (or larger for many concurrent users), your key pair, and a security group as above. Plans, templates and the database live on the root volume, so size it for the data you expect.

To launch with the AWS CLI instead, replace the values in angle brackets:

aws ec2 run-instances --image-id <ami-id-from-the-listing> --instance-type m5.large \
  --key-name <your-key-pair> --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=dmproadmap}]'

First boot takes about a minute after the instance is running. It creates the database and generates the secrets, the administrator and the certificate, then starts DMPRoadmap.

First boot uses the instance's public IP address as its name, or its private address if it has no public one. It also serves the instance's EC2 public DNS name and its private address.

2

Connect to your instance

Connect over SSH. The SSH user for Ubuntu 24.04 is ubuntu:

ssh -i <your-key.pem> ubuntu@<public-ip>

The login message shows the instance address and where the administrator's password is.

3

Check the services

Confirm that all five services are active:

systemctl is-active sac-dmproadmap-vpc-cidrs sac-dmproadmap-egress postgresql@16-main dmproadmap nginx
active active active active active

The dmproadmap-firstboot service runs once, on the first boot, and shows inactive on every later boot.

Only SSH, HTTP and HTTPS are public. puma and PostgreSQL listen on the loopback address:

sudo ss -Htln | awk '{print $4}' | sort -u
0.0.0.0:22 0.0.0.0:443 0.0.0.0:80 127.0.0.1:3000 127.0.0.1:5432 127.0.0.53%lo:53 127.0.0.54:53 [::]:22 [::]:443 [::]:80

The addresses 127.0.0.53 and 127.0.0.54 belong to Ubuntu's local DNS resolver.

4

Read the address and the administrator

Everything that first boot generated is in /root/dmproadmap-credentials.txt (root only). Print the address, the host name, the administrator's email and the certificate's SHA-256 fingerprint:

sudo grep -E '^DMPROADMAP_(URL|HOST|ADMIN_EMAIL|TLS_SHA256)=' /root/dmproadmap-credentials.txt
DMPROADMAP_URL=https://203.0.113.10/ DMPROADMAP_HOST=203.0.113.10 DMPROADMAP_ADMIN_EMAIL=admin@dmproadmap.invalid DMPROADMAP_TLS_SHA256=76:CC:AD:EA:F4:DB:CB:15:8E:8A:33:B1:AC:94:E0:D4:05:2C:64:3E:88:AE:CF:30:A4:80:5A:9B:59:29:00:16

The same file holds DMPROADMAP_ADMIN_PASSWORD. Read it with sudo cat /root/dmproadmap-credentials.txt when you need it, and keep it out of tickets and chat.

The certificate is self-signed for this instance. When your browser asks you to trust it, compare its SHA-256 fingerprint with DMPROADMAP_TLS_SHA256.

5

Sign in

Open DMPROADMAP_URL (for example https://203.0.113.10/) in a browser and sign in with DMPROADMAP_ADMIN_EMAIL and DMPROADMAP_ADMIN_PASSWORD:

A wrong password is refused. So are the upstream demo logins such as super_admin@example.com with password123, because those accounts do not exist on the image. After you sign in, My Dashboard lists your plans:

Change the administrator's password from Edit profile once you have signed in, or set one from the shell (Step 10).

6

Check the whole instance

Run the self-test, which signs in over HTTPS with this instance's certificate pinned. It checks the security headers and confirms that self-registration is refused while it is closed. It also confirms that a wrong password and the seeded super_admin@example.com login are refused, and that the administrator signs in and reaches the plans page:

sudo dmproadmap-selftest
ok GET / (the sign-in page) answers 200 over HTTPS ok the page carries a CSRF token ok the page shows the sign-in form ok Strict-Transport-Security is sent ok Content-Security-Policy (script-src 'self', frame-ancestors 'none') ok Referrer-Policy: same-origin ok X-Frame-Options: DENY ok the session cookie is Secure and HttpOnly ok no X-Runtime / X-Request-Id leaks ok registration is CLOSED: GET /users/sign_up answers 403 ok registration is CLOSED: POST /users (account create) answers 403 ok /rails/info is not served (404) ok /users/auth/shibboleth is not served (404) ok a WRONG password is refused (/plans redirects to sign-in, 302) ok the upstream seeded super_admin@example.com / password123 is refused (302) ok the administrator signs in (POST 302) and /plans answers 200 DMPROADMAP_SELFTEST_OK
7

Create and export a plan

Choose Create plan and give the research project a title. Pick your organization and funder, or tick that they are not listed to use your organization's default template.

A new instance has DMPRoadmap's own example data: the default organization Curation Center, a funder Government Agency with its Department of Testing Award template, and University of Exampleland. Add your own institution and funders as in Step 8:

The plan opens on its Project Details tab, and the Write Plan tab holds the template's questions. Download exports the plan as PDF (rendered by wkhtmltopdf on the instance), Word (DOCX), CSV, HTML, plain text or JSON:

To take a plan off your dashboard, open its Actions menu on My Dashboard and choose Remove.

8

Templates and organizations

As super administrator, you manage the templates your organization offers under Admin, then Templates. Each template is built from phases, sections and questions, with guidance.

Your account belongs to the default organization, Curation Center. Rename it, or add your own institution and its funders, under Admin, then Organisations. Give your colleagues their roles under Admin, then Users:

Organization logos need ImageMagick, which is not on the image (it is in Ubuntu's community-supported universe archive). To enable logo uploads, install it yourself with sudo apt install imagemagick and restart DMPRoadmap.

9

Self-registration

Self-registration is closed on a new instance. The sign-up page and the account-create request are refused, and new users join through an administrator's invitation (which needs mail, Step 11).

Check the status, then see the refusal from the instance itself. The certificate's directory is root only, so first copy the public certificate to your home directory:

sudo dmproadmap-registration status
dmproadmap-registration: CLOSED (new accounts by administrator invitation only)

The sign-up page answers 403 (Forbidden):

sudo cat /etc/ssl/dmproadmap/dmproadmap.crt > ~/dmproadmap.crt curl -s --cacert ~/dmproadmap.crt --resolve <DMPROADMAP_HOST>:443:127.0.0.1 -o /dev/null -w '%{http_code}\n' \
  "https://<DMPROADMAP_HOST>/users/sign_up"
403

The home page still shows a Create account tab. It is part of DMPRoadmap's page, and submitting it is refused while registration is closed.

Open registration only when anyone who can reach the site may create an account, for example behind your VPN or a security group limited to your institution:

sudo dmproadmap-registration open
# anyone who can reach the site may create an account
sudo dmproadmap-registration close
# back to invitations only

The change takes effect at once, and no restart is needed.

10

Manage users and passwords

Manage users, their roles and their organizations in the web interface under Admin, then Users.

From the shell, you can set a new password for any user without mail. The command reads the password from standard input, never from the command line, and the password must be at least 12 characters:

sudo dmproadmap-set-password admin@example.org
# then type the new password openssl rand -base64 18 | sudo dmproadmap-set-password user@example.org

To run a Rails command as the application, for example a console query, use dmproadmap-run:

sudo dmproadmap-run rails runner 'puts "users=#{User.count} orgs=#{Org.count} templates=#{Template.count}"' | tail -1
users=1 orgs=3 templates=3
11

Send mail

DMPRoadmap sends invitations, password resets and plan-sharing notices by email. The image has no mail server, and delivery is off until you configure a relay (Amazon SES or your institution's SMTP server). Add the settings to /etc/dmproadmap/dmproadmap.env (root only) and restart:

SMTP_ADDRESS=email-smtp.us-east-1.amazonaws.com SMTP_PORT=587 SMTP_USERNAME=<your SMTP user> SMTP_PASSWORD=<your SMTP password> SMTP_DOMAIN=example.org DMPROADMAP_MAIL_FROM=dmp@example.org
sudo systemctl restart dmproadmap

A relay with a public address works as is. A relay on a private address in your VPC must first be allowed through the egress backstop (Step 12).

12

Reach a service in your VPC

The egress backstop refuses DMPRoadmap every private address and this instance's own VPC ranges, so a fresh instance cannot be turned into a scanner of your network. Print the ranges it read at boot:

sudo dmproadmap-vpc-cidrs --print
source imds 4 172.31.0.0/16

To let DMPRoadmap reach an SMTP relay or an identity provider on a private address, add its CIDR, one per line, to /etc/sac/dmproadmap-egress-allow. Then reload the backstop and restart DMPRoadmap:

echo '10.0.1.25/32' | sudo tee -a /etc/sac/dmproadmap-egress-allow
sudo systemctl reload sac-dmproadmap-egress && sudo systemctl restart dmproadmap

Only private ranges are accepted (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 100.64.0.0/10 and fc00::/7). The metadata service and link-local addresses can never be allowed. A file with any other entry is refused whole, and the previous rules stay in place.

If DMPRoadmap does not start after a reboot. The backstop is fail closed. The instance reads its VPC ranges from EC2 metadata at every boot (with retries), then from cloud-init's copy, then, on later boots only, from the last list this instance recorded. If none of them gives the ranges (for example after the metadata service was switched off on the instance), DMPRoadmap refuses to start, and journalctl -u dmproadmap -u sac-dmproadmap-vpc-cidrs says so.

Turn IMDSv2 back on (aws ec2 modify-instance-metadata-options --instance-id <id> --http-endpoint enabled --http-tokens required), then restart the services:

sudo systemctl restart sac-dmproadmap-vpc-cidrs sac-dmproadmap-egress dmproadmap nginx
13

Use your own domain and certificate

Point a DNS name at the instance, then make it the instance's name with the command below. The command writes the nginx host names (requests for any other name are dropped) and generates a new self-signed certificate for those names. It then restarts nginx and DMPRoadmap, so links in emails use the new name:

sudo dmproadmap-set-domain dmp.example.com

To use a certificate from a certificate authority instead, put the full chain and key in /etc/ssl/dmproadmap/dmproadmap.crt and /etc/ssl/dmproadmap/dmproadmap.key (root only, mode 0600 for the key). Then run sudo nginx -t && sudo systemctl reload nginx.

If the instance's public address changes after a stop and start, run dmproadmap-set-domain again with the new address.

Single sign-on. DMPRoadmap supports ORCID and Shibboleth sign-in upstream. Both need credentials registered with the identity provider, and the provider's address must be allowed in the Content Security Policy. Ask SecureAnyCloud support if you want to enable them.

14

Versions, licenses and source

Print the provenance record to see the exact versions and checksums of the components on the image:

cat /usr/share/doc/dmproadmap/PROVENANCE
DMPRoadmap 6.0.0 (MIT) - https://github.com/DMPRoadmap/roadmap/archive/refs/tags/v6.0.0.tar.gz sha256 0720f5da06f572338e735f6e0979e8631af05a4bc9b44770a7735fc1e8b91af4 Ruby 3.4.12 - https://cache.ruby-lang.org/pub/ruby/3.4/ruby-3.4.12.tar.gz sha256 5e5d85ad93b0adcccbad47733680f4892bd0078e3342437f7babce01c1872479 (built with --enable-shared into /opt/dmproadmap/ruby) Bundler 2.7.2; Gemfile.lock sha256 cc1a80e47c035f66f3efdfcba776c4d39a818ed2908decb309382fd8da192f4f (tag: 01dd6cafb822712ebc28a97bd2f78f9f7c64f5b544def5e0627f47239aa4fcd1; raised in range: rails rack loofah nokogiri addressable crass rails-html-sanitizer) Node.js 24.18.0 + Yarn 1.22.22 (asset build only, not shipped); yarn.lock sha256 19bf4fd2b327f8db135d7e50a10cfb8eb9e882e66f90d84ab565136515d34dc0 (tag: a5d1ef521c1a7e57e6ba89b33b645a07e1048151ebd845fa083a03960c447c9d; raised in range: tinymce js-cookie) wkhtmltopdf /opt/dmproadmap/wkhtmltopdf/wkhtmltopdf sha256 b0dcf90d3c5f7201da3a7014bff66405ebdfa4338e67dfd9dc8031dee3772799 (from wkhtmltopdf-binary 0.12.6.10, wkhtmltopdf_ubuntu_22.04_amd64.gz) Reference data /usr/share/sac/dmproadmap/roadmap-reference.dump (upstream db:seed with every seeded user destroyed)

DMPRoadmap is free software under the MIT license (/usr/share/doc/dmproadmap/LICENSE.md). The same directory holds the exact Gemfile.lock and yarn.lock the image was built from, next to upstream's originals. You can see every Ruby gem and JavaScript package and its version.

Support

SecureAnyCloud provides 24/7 support for this image, with a guaranteed 24-hour response.

DMPRoadmap is a trademark of its respective owners. SecureAnyCloud packages and configures it and is not affiliated with or endorsed by the DMPRoadmap project, the Digital Curation Centre or the California Digital Library.

Deploy on AWS

Launch DMPRoadmap 6.0.0 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS