D6
Applications AWS

DMPRoadmap 6.0.0 on AWS User Guide

| Product: DMPRoadmap 6.0.0 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the DMPRoadmap 6.0.0 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg GIS, health and research applications listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

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 organisations, templates, guidance and users from the web interface.

The cloudimg image is a hardened, ready-to-use DMPRoadmap server:

  • 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 organisations 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 and 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, and 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), 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; requests for any other host name are dropped. You can change it 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). New users join by administrator invitation while it is closed.
  • 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), the application to 20 requests a second, and 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 organisations, ORCID identifiers and funders on the internet, so the dmproadmap, www-data (nginx) and postgres accounts are refused, by iptables and by systemd, 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, 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 are 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

  • 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: 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.

Step 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 your Region, then 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.

With the AWS CLI (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, generates the secrets, the administrator and the certificate, then DMPRoadmap starts. First boot uses the instance's public IP address as its name (or its private address if it has no public one), and also serves its EC2 public DNS name and its private address.

Step 2: Connect to your instance

Operating system SSH user
Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

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

Step 3: Check the services

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

(dmproadmap-firstboot 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

(127.0.0.53 and 127.0.0.54 are Ubuntu's local DNS resolver.)

Step 4: Read the address and the administrator

Everything first boot generated is in /root/dmproadmap-credentials.txt (root only). The address, the host name, the administrator's e-mail 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.

Step 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:

The DMPRoadmap home page over HTTPS with the sign-in form

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

My Dashboard after signing in as this instance's super administrator

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

Step 6: Check the whole instance

The self-test signs in over HTTPS with this instance's certificate pinned. It proves the security headers, that self-registration is refused while it is closed, 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

Step 7: Create and export a plan

Choose Create plan, give the research project a title, and pick your organisation and funder, or tick that they are not listed to use your organisation's default template. A new instance has DMPRoadmap's own example data: the default organisation 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 Create a new plan page, with the project title and the organisation and funder choices

The plan opens on its Project Details tab; 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:

The Download tab of a plan, with the PDF and DOCX formats

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

Step 8: Templates and organisations

As super administrator you manage the templates your organisation offers under Admin, then Templates: each is built from phases, sections and questions, with guidance. Your account belongs to the default organisation, Curation Center; rename it, or add your own institution and its funders, under Admin, then Organisations, and give your colleagues their roles under Admin, then Users:

The template administration page listing the three example templates of a new instance

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

Step 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 it, and 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; no restart is needed.

Step 10: Manage users and passwords

Users, their roles and their organisations are managed in the web interface (Admin, then Users). From the shell, set a new password for any user without mail (the password is read from standard input, never from the command line, and 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

Step 11: Send mail

DMPRoadmap sends invitations, password resets and plan-sharing notices by e-mail. 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 be allowed through the egress backstop first (Step 12).

Step 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. 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/cloudimg/dmproadmap-egress-allow, then reload the backstop and restart DMPRoadmap:

echo '10.0.1.25/32' | sudo tee -a /etc/cloudimg/dmproadmap-egress-allow
sudo systemctl reload cloudimg-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, and a file with any other entry is refused whole, keeping the previous rules.

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 cloudimg-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:

sudo systemctl restart cloudimg-dmproadmap-vpc-cidrs cloudimg-dmproadmap-egress dmproadmap nginx

Step 13: Use your own domain and certificate

Point a DNS name at the instance, then make it the instance's name. The command writes the nginx host names (requests for any other name are dropped), generates a new self-signed certificate for the names and restarts nginx and DMPRoadmap, so links in e-mails 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 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 allowed in the Content Security Policy; ask cloudimg support if you want to enable them.

Step 14: Versions, licences and source

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/cloudimg/dmproadmap/roadmap-reference.dump (upstream db:seed with every seeded user destroyed)

DMPRoadmap is free software under the MIT licence (/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, so you can see every Ruby gem and JavaScript package and its version.

Support

cloudimg provides 24/7 support for this image, with a guaranteed 24 hour response. DMPRoadmap is a trademark of its respective owners; cloudimg packages and configures it and is not affiliated with or endorsed by the DMPRoadmap project, the Digital Curation Centre or the California Digital Library.