AWSTemplateFormatVersion: "2010-09-09" Description: >- (WWPS-GLS-WF-ORCHESTRATOR-CROMWELL) Creates resources specific to running Cromwell on AWS Mappings: TagMap: default: architecture: "genomics-workflows" solution: "cromwell" tags: - Key: "architecture" Value: "genomics-workflows" - Key: "solution" Value: "cromwell" Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: "Stack Configuration" Parameters: - Namespace - GWFCoreNamespace - Label: default: "Network Configuration" Parameters: - VpcId - ServerSubnetID - DBSubnetIDs - Label: default: "Instance Configuration" Parameters: - LatestAmazonLinuxAMI - InstanceType - InstanceName - SSHLocation - HTTPLocation - EC2RootVolumeSize - Label: default: "Cromwell Configuration" Parameters: - CromwellVersion - CromwellVersionSpecified - CromwellJarUrl - S3DataBucketARNs - DBUsername - DBPassword ParameterLabels: VpcId: default: "VPC ID" ServerSubnetID: default: "Server Subnet ID" InstanceName: default: "Instance Name" LatestAmazonLinuxAMI: default: "Latest Amazon Linux AMI" SSHLocation: default: "SSH Address Range" HTTPLocation: default: "HTTP Address Range" S3DataBucketARNs: default: "S3 Open Data Bucket ARNs" CromwellVersion: default: "Cromwell Version" CromwellVersionSpecified: default: "Cromwell Version Specified" DBSubnetIDs: default: "Database Subnet IDs" DBUsername: default: "Cromwell Database Username" DBPassword: default: "Cromwell Database Password" EC2RootVolumeSize: default: "Cromwell EC2 Root Volume Size in GBs" # Parameters Parameters: Namespace: Type: String Description: >- Namespace (e.g. project name) to use to label resources. GWFCoreNamespace: Type: String Description: >- Namespace of the GWFCore deployment to use. InstanceType: Description: >- EC2 instance type. Cromwell itself does not require much compute power. A t3.medium should be sufficient. Larger instances are recommended for concurrent workflow scenarios. If you want to run this server on the free tier, use a t3.micro. Type: String Default: t3.medium AllowedValues: - t3.micro - t3.medium - t3.large - t3.xlarge - t3.2xlarge ConstraintDescription: "Must be 't3' instance type." VpcId: Type: AWS::EC2::VPC::Id Description: Recommended to use the Default VPC here ServerSubnetID: Type: AWS::EC2::Subnet::Id Description: Subnet for the Cromwell server. For public access, use a public subnet. LatestAmazonLinuxAMI: Description: The latest Amazon Linux AMI Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 AllowedValues: - /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 CromwellVersion: Type: String Description: >- Version of Cromwell to install. "latest" will retrieve the currently released version of Cromwell from Github. AllowedValues: - latest - specify ... Default: latest CromwellVersionSpecified: Type: String Description: >- Specific version of Cromwell to install. Must match a released version number. For example, 52, 52.1, etc. The minimum supported version is 52. Ignored if "Cromwell Version" is set to "latest". Default: "" CromwellJarUrl: Type: String Description: >- URL to a pre-built cromwell-*.jar file. Example: https://mycicdserver.com/build/cromwell-XX-SNAP.jar. If this is specifed, CromwellVersion is ignored. Default: "https://github.com/henriqueribeiro/cromwell/releases/download/78-AWS/cromwell-78-AWS.jar" DBSubnetIDs: Type: List Description: Minimum 2 subnets for the Cromwell Database. Private subnets are recommended. DBUsername: Type: String Description: >- The master username for the Aurora MySQL RDS cluster that will be used as Cromwell's database Default: cromwell MaxLength: 16 MinLength: 1 AllowedPattern: "^[a-zA-Z]{1}[a-zA-Z0-9]{0,15}$" ConstraintDescription: >- DBUsername must have 1 to 16 alphanumeric characters. First character must be a letter DBPassword: Type: String NoEcho: true Description: >- The master password for the Aurora MySQL RDS cluster that will be used as Cromwell's database MinLength: 8 AllowedPattern: '^[ -~][^"@/]{7,}$' ConstraintDescription: >- DBPassword must have at least 8 printable ASCII characters. Can't contain any of the following: / (slash), "(double quote) and @ (at sign). InstanceName: Type: String Default: cromwell-server Description: The name of the instance that is created SSHLocation: Description: >- The IP address range that can be used to SSH to the EC2 instances. In a production environment we recommend limiting this to a trusted range. Type: String MinLength: '9' MaxLength: '18' Default: 0.0.0.0/0 AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})" ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. HTTPLocation: Description: >- The IP address range that has HTTP access to the EC2 instances. In a production environment we recommend limiting this to a trusted range. Type: String MinLength: '9' MaxLength: '18' Default: 0.0.0.0/0 AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})" ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. S3DataBucketARNs: Description: Open datasets on AWS S3 for workflow inputs Type: CommaDelimitedList Default: "arn:aws:s3:::gatk-test-data/*,arn:aws:s3:::broad-references/*" EC2RootVolumeSize: Description: the size in GBs for the root volume Type: Number Default: 8 UseFSx: Type: String AllowedValues: - "Yes" - "No" Default: "No" FSxFileSystemID: Description: The FSx ID to be used Type: String Default: "NA" FSxFileSystemMount: Description: The FSx Mount to be used Type: String Default: "NA" FSxSecurityGroupId: Description: the Security Group Id for the FSx Type: String Default: "NA" Conditions: GetLatestCromwellVersion: Fn::Equals: - !Ref CromwellVersion - latest NoCromwellJar: Fn::Equals: - !Ref CromwellJarUrl - "" UseCromwellJar: Fn::Not: - Condition: NoCromwellJar FsxCondition: !Equals [ !Ref UseFSx, "Yes"] # Resources Resources: Ec2InstanceRole: Type: AWS::IAM::Role Properties: ManagedPolicyArns: - "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" Policies: - PolicyName: !Sub CromwellServer-BatchQueue-Access-${AWS::Region} PolicyDocument: Version: 2012-10-17 Statement: Effect: Allow Resource: "*" Action: - "batch:DescribeJobQueues" - "batch:DeregisterJobDefinition" - "batch:TerminateJob" - "batch:DescribeJobs" - "batch:CancelJob" - "batch:SubmitJob" - "batch:RegisterJobDefinition" - "batch:DescribeJobDefinitions" - "batch:ListJobs" - "batch:DescribeComputeEnvironments" - "ecs:DescribeContainerInstances" - "imagebuilder:GetComponent" - "imagebuilder:GetContainerRecipe" - "ecr:GetAuthorizationToken" - "ecr:BatchGetImage" - "ecr:InitiateLayerUpload" - "ecr:UploadLayerPart" - "ecr:CompleteLayerUpload" - "ecr:BatchCheckLayerAvailability" - "ecr:GetDownloadUrlForLayer" - "ecr:PutImage" - "ecr:CreateRepository" - PolicyName: !Sub CromwellServer-S3-Access-${AWS::Region} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Resource: - !Join ["", ["arn:aws:s3:::", !Sub "{{resolve:ssm:/gwfcore/${GWFCoreNamespace}/s3-bucket:1}}"]] - !Join ["", ["arn:aws:s3:::", !Sub "{{resolve:ssm:/gwfcore/${GWFCoreNamespace}/s3-bucket:1}}", "/*"]] Action: - "s3:*" - Effect: Allow Resource: "*" Action: - "s3:ListBucket" - "s3:ListAllMyBuckets" - Effect: Allow Resource: !Ref S3DataBucketARNs Action: - "s3:GetObject" - "s3:ListBucket" - PolicyName: !Sub CromwellServer-CloudWatch-Access-${AWS::Region} PolicyDocument: Version: 2012-10-17 Statement: Effect: Allow Resource: "arn:aws:logs:*:*:*" Action: - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" - "logs:DescribeLogStreams" - PolicyName: !Sub CromwellSecretManager-Access-${AWS::Region} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Resource: "*" Action: - "secretsmanager:ListSecrets" - Effect: Allow Resource: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:cromwell/credentials/* Action: - "secretsmanager:PutSecretValue" - "secretsmanager:CreateSecret" - "secretsmanager:UpdateSecret" - PolicyName: !Sub CromwellServer-Notification-Access-${AWS::Region} PolicyDocument: Version: 2012-10-17 Statement: Effect: Allow Resource: "*" Action: - "sns:Publish" - "events:PutEvents" AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: ec2.amazonaws.com Action: sts:AssumeRole EC2InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: "/" Roles: - Ref: Ec2InstanceRole EC2SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Cromwell server access via SSH and HTTP/HTTPS VpcId: !Ref VpcId Tags: - Key: Name Value: !Sub cromwell-server-sg-${Namespace} - Key: architecture Value: !FindInMap ["TagMap", "default", "architecture"] - Key: solution Value: !FindInMap ["TagMap", "default", "solution"] SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: Ref: SSHLocation - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: Ref: HTTPLocation - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: Ref: HTTPLocation FSxSGIngressTCP: Condition: FsxCondition DependsOn: EC2SecurityGroup Type: AWS::EC2::SecurityGroupIngress Properties: Description: "Allow TCP Connections for the Ec2 Cromwell security group to FSx SG" GroupId: !Ref FSxSecurityGroupId SourceSecurityGroupId: !Ref EC2SecurityGroup IpProtocol: tcp FromPort: 0 ToPort: 65535 EC2Instance: Type: AWS::EC2::Instance Metadata: cfn-lint: config: ignore_checks: - W4002 AWS::CloudFormation::Init: configSets: default: - config1 - config2 - config3 - config4 config1: files: "/etc/awslogs/awslogs.conf": content: | [general] state_file = /var/lib/awslogs/agent-state [cromwell-server] file = /home/ec2-user/cromwell-server.log log_group_name = cromwell-server log_stream_name = %%INSTANCE-ID%% mode: 000664 owner: root group: root "/etc/awslogs/awscli.conf": content: !Sub | [plugins] cwlogs = cwlogs [default] region = ${AWS::Region} mode: 000664 owner: root group: root "/home/ec2-user/get_cromwell.sh": content: !Sub - | #!/bin/bash url=${DownloadUrl} if [[ $url == s3://* ]]; then aws s3 cp $url . else curl --retry 5 --retry-connrefused -LO $url fi ln -s $(find . | grep "cromwell.*\.jar") cromwell.jar - DownloadUrl: Fn::If: - UseCromwellJar - !Ref CromwellJarUrl - !Sub - $(curl --silent --retry 5 --retry-connrefused https://api.github.com/repos/broadinstitute/cromwell/releases/${CromwellVersionPath} | jq -r .assets[0].browser_download_url) - CromwellVersionPath: Fn::If: - GetLatestCromwellVersion - !Ref CromwellVersion - !Join ["/", ["tags", !Ref CromwellVersionSpecified]] mode: "000755" owner: "ec2-user" group: "ec2-user" "/home/ec2-user/get_cromwell_tools.sh": content: | #!/bin/bash url=$(curl --silent --retry 5 --retry-connrefused https://api.github.com/repos/broadinstitute/cromwell/releases/latest | jq -r .assets[1].browser_download_url) curl --retry 5 --retry-connrefused -LO $url curl --retry 5 --retry-connrefused -LO https://raw.githubusercontent.com/broadinstitute/cromshell/master/cromshell chmod +x cromshell sudo mv cromshell /usr/local/bin/ mkdir /home/ec2-user/.cromshell echo "http://localhost:8000" > /home/ec2-user/.cromshell/cromwell_server.config sudo chmod 777 -R /home/ec2-user/.cromshell mode: "000755" owner: "ec2-user" group: "ec2-user" "/home/ec2-user/cromwell_local.conf": content: !Sub - | include required(classpath("application")) webservice { interface = localhost port = 8000 } akka { http { server { request-timeout = 600s idle-timeout = 600s } } } system { job-rate-control { jobs = 1 per = 2 second } } aws { application-name = "cromwell" auths = [{ name = "default" scheme = "default" }] region = "${AWS::Region}" } database { profile = "slick.jdbc.MySQLProfile$" db { driver = "com.mysql.cj.jdbc.Driver" url = "jdbc:mysql://${DBAddress}/cromwell?rewriteBatchedStatements=true&useSSL=false" user = "${DBUsername}" password = "${DBPassword}" connectionTimeout = 30000 } } call-caching { enabled = true invalidate-bad-cache-results = true } engine { filesystems { local { auth = "default" } } } backend { default = "AWSBATCH" providers { AWSBATCH { actor-factory = "cromwell.backend.impl.aws.AwsBatchBackendLifecycleActorFactory" config { numSubmitAttempts = 10 numCreateDefinitionAttempts = 10 root = "/${S3Bucket}/cromwell-execution" auth = "default" default-runtime-attributes { queueArn = "${BatchQueue}" , scriptBucketName = "${S3Bucket}" } filesystems { local { auth = "default" duplication-strategy: [ "soft-link", "copy" ] fsx = [${S3Bucket}] caching { hashing-strategy: "path+modtime" } } } } } } } - DBAddress: !GetAtt RDSCluster.Endpoint.Address BatchQueue: !Sub '{{resolve:ssm:/gwfcore/${GWFCoreNamespace}/job-queue/default:1}}' S3Bucket: !Sub "{{resolve:ssm:/gwfcore/${GWFCoreNamespace}/s3-bucket:1}}" mode: "000644" owner: "ec2-user" group: "ec2-user" "/home/ec2-user/cromwell_s3.conf": content: !Sub - | include required(classpath("application")) webservice { interface = localhost port = 8000 } akka { http { server { request-timeout = 300s idle-timeout = 300s } } } system { job-rate-control { jobs = 1 per = 2 second } } aws { application-name = "cromwell" auths = [{ name = "default" scheme = "default" }] region = "${AWS::Region}" } database { profile = "slick.jdbc.MySQLProfile$" db { driver = "com.mysql.cj.jdbc.Driver" url = "jdbc:mysql://${DBAddress}/cromwell?rewriteBatchedStatements=true&useSSL=false" user = "${DBUsername}" password = "${DBPassword}" connectionTimeout = 30000 } } call-caching { enabled = true invalidate-bad-cache-results = true } engine { filesystems { s3 { auth = "default" } } } backend { default = "AWSBATCH" providers { AWSBATCH { actor-factory = "cromwell.backend.impl.aws.AwsBatchBackendLifecycleActorFactory" config { numSubmitAttempts = 10 numCreateDefinitionAttempts = 10 root = "s3://${S3Bucket}/cromwell-execution" auth = "default" default-runtime-attributes { queueArn = "${BatchQueue}" , scriptBucketName = "${S3Bucket}" } filesystems { s3 { auth = "default" duplication-strategy: [ "hard-link", "soft-link", "copy" ] } } } } } } - DBAddress: !GetAtt RDSCluster.Endpoint.Address BatchQueue: !Sub '{{resolve:ssm:/gwfcore/${GWFCoreNamespace}/job-queue/default:1}}' S3Bucket: !Sub "{{resolve:ssm:/gwfcore/${GWFCoreNamespace}/s3-bucket:1}}" mode: "000644" owner: "ec2-user" group: "ec2-user" "/home/ec2-user/supervisord.conf": mode: "000644" owner: "ec2-user" group: "ec2-user" content: !If - FsxCondition - | [unix_http_server] file=/home/ec2-user/supervisor.sock ; the path to the socket file [supervisord] logfile=/home/ec2-user/supervisord.log ; main log file; default $CWD/supervisord.log logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB logfile_backups=10 ; # of main logfile backups; 0 means none, default 10 loglevel=info ; log level; default info; others: debug,warn,trace pidfile=/home/ec2-user/supervisord.pid ; supervisord pidfile; default supervisord.pid nodaemon=false ; start in foreground if true; default false minfds=1024 ; min. avail startup file descriptors; default 1024 minprocs=200 ; min. avail process descriptors;default 200 [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///home/ec2-user/supervisor.sock ; use a unix:// URL for a unix socket [program:cromwell-server] command=java -Dconfig.file=cromwell_local.conf -XX:MaxRAMPercentage=85.0 -jar cromwell.jar server ; the program (relative uses PATH, can take args) directory=/home/ec2-user ; directory to cwd to before exec (def no cwd) user=ec2-user ; setuid to this UNIX account to run the program redirect_stderr=true ; redirect proc stderr to stdout (default false) stdout_logfile=/home/ec2-user/cromwell-server.log ; stdout log path, NONE for none; default AUTO - | [unix_http_server] file=/home/ec2-user/supervisor.sock ; the path to the socket file [supervisord] logfile=/home/ec2-user/supervisord.log ; main log file; default $CWD/supervisord.log logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB logfile_backups=10 ; # of main logfile backups; 0 means none, default 10 loglevel=info ; log level; default info; others: debug,warn,trace pidfile=/home/ec2-user/supervisord.pid ; supervisord pidfile; default supervisord.pid nodaemon=false ; start in foreground if true; default false minfds=1024 ; min. avail startup file descriptors; default 1024 minprocs=200 ; min. avail process descriptors;default 200 [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///home/ec2-user/supervisor.sock ; use a unix:// URL for a unix socket [program:cromwell-server] command=java -Dconfig.file=cromwell_s3.conf -XX:MaxRAMPercentage=85.0 -jar cromwell.jar server ; the program (relative uses PATH, can take args) directory=/home/ec2-user ; directory to cwd to before exec (def no cwd) user=ec2-user ; setuid to this UNIX account to run the program redirect_stderr=true ; redirect proc stderr to stdout (default false) stdout_logfile=/home/ec2-user/cromwell-server.log ; stdout log path, NONE for none; default AUTO "/etc/nginx/nginx.conf": mode: "000644" content: | # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; index index.html index.htm; server { # Config options for a TLS enabled server listen 80; listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; server_name localhost; root /usr/share/nginx/html; ssl_certificate "/etc/pki/tls/certs/server.crt"; ssl_certificate_key "/etc/pki/tls/certs/server.key"; # It is *strongly* recommended to generate unique DH parameters # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048 #ssl_dhparam "/etc/pki/nginx/dhparams.pem"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; # redirect all non-ssl traffic to ssl if ($ssl_protocol = "") { rewrite ^ https://$host$request_uri? permanent; } location / { proxy_pass http://localhost:8000; } # redirect server error pages to the static page /40x.html # error_page 404 /404.html; location = /40x.html { } # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { } } } "/home/ec2-user/supervisord.log": content: "\n" mode: "000664" owner: "ec2-user" group: "ec2-user" "/home/ec2-user/.aws/config": content: !Sub | [default] region = ${AWS::Region} mode: "000644" owner: "ec2-user" group: "ec2-user" "/home/ec2-user/mount_fsx.sh": content: !Sub - | #!/bin/bash if [[ ${FSXFSId} != "NA" ]]; then sudo mkdir /${S3Bucket} sudo mount -t lustre -o noatime,flock ${FSXFSId}.fsx.${AWS::Region}.amazonaws.com@tcp:/${FSXFSMount} /${S3Bucket} sudo chmod -R 777 /${S3Bucket} fi - FSXFSId: !Ref FSxFileSystemID FSXFSMount: !Ref FSxFileSystemMount S3Bucket: !Sub "{{resolve:ssm:/gwfcore/${GWFCoreNamespace}/s3-bucket:1}}" mode: "000755" owner: "ec2-user" group: "ec2-user" commands: 00_get_instance_id: command: curl -s http://169.254.169.254/latest/meta-data/instance-id/ > /etc/instance-id 01_set_log_stream_name: command: sed -i -e "s/%%INSTANCE-ID%%/`cat /etc/instance-id`/g" /etc/awslogs/awslogs.conf config2: commands: 00_enable_awslogs: command: "systemctl enable awslogsd" 01_start_awslogs: command: "systemctl start awslogsd" 02_enable_nginx: command: "systemctl enable nginx" 03_start_nginx: command: "systemctl start nginx" config3: commands: 00_get_cromwell: cwd: "/home/ec2-user/" command: "./get_cromwell.sh" 01_chown_cromwell: cwd: "/home/ec2-user/" command: "chown ec2-user:ec2-user cromwell*.jar" 02_start_cromwell: cwd: "/home/ec2-user" command: "sudo -u ec2-user /usr/local/bin/supervisord" config4: commands: 00_get_cromwell_tools: cwd: "/home/ec2-user/" command: "./get_cromwell_tools.sh" 01_chown_womtool: cwd: "/home/ec2-user/" command: "chown ec2-user:ec2-user womtool*.jar" 02_mount_fsx: cwd: "/home/ec2-user/" command: "/home/ec2-user/mount_fsx.sh" Properties: ImageId: !Ref LatestAmazonLinuxAMI InstanceType: !Ref InstanceType IamInstanceProfile: !Ref EC2InstanceProfile Tags: - Key: Name Value: !Sub ${InstanceName}-${Namespace} - Key: architecture Value: !FindInMap ["TagMap", "default", "architecture"] - Key: solution Value: !FindInMap ["TagMap", "default", "solution"] BlockDeviceMappings: - DeviceName: "/dev/xvda" Ebs: VolumeSize: !Ref EC2RootVolumeSize UserData: Fn::Base64: !Sub | #!/bin/bash -x yum -y update yum install -y aws-cfn-bootstrap yum install -y jq awslogs python3 java mailx git amazon-linux-extras install -y nginx1 lustre2.10 pip3 install supervisor # create a self-signed certificate cd /tmp openssl genrsa 2048 > server.key openssl req -new -key server.key -out csr.pem -subj "/C=US/ST=WA/L=Seattle/O=anon/OU=anon/CN=selfsigned/emailAddress=selfsigned" openssl x509 -req -days 365 -in csr.pem -signkey server.key -out server.crt cp server.crt server.key /etc/pki/tls/certs/ rm -f server.crt server.key csr.pem /opt/aws/bin/cfn-init --verbose --stack ${AWS::StackName} --resource EC2Instance --region ${AWS::Region} /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource EC2Instance --region ${AWS::Region} NetworkInterfaces: - AssociatePublicIpAddress: true DeviceIndex: "0" GroupSet: - !Ref EC2SecurityGroup SubnetId: !Ref ServerSubnetID CreationPolicy: ResourceSignal: Timeout: PT15M RDSSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Limit access to Cromwell DB to just the Cromwell server security group VpcId: !Ref VpcId SecurityGroupIngress: - IpProtocol: tcp SourceSecurityGroupId: !GetAtt EC2SecurityGroup.GroupId ToPort: 3306 FromPort: 3306 Tags: - Key: Name Value: !Sub cromwell-db-sg-${Namespace} - Key: architecture Value: !FindInMap ["TagMap", "default", "architecture"] - Key: solution Value: !FindInMap ["TagMap", "default", "solution"] DBSubnetGroup: Type: 'AWS::RDS::DBSubnetGroup' Properties: DBSubnetGroupDescription: !Ref 'AWS::StackName' SubnetIds: !Ref DBSubnetIDs Tags: - Key: Name Value: !Sub cromwell-db-subnet-group-${Namespace} - Key: architecture Value: !FindInMap ["TagMap", "default", "architecture"] - Key: solution Value: !FindInMap ["TagMap", "default", "solution"] RDSCluster: Type: 'AWS::RDS::DBCluster' Properties: MasterUsername: !Ref DBUsername MasterUserPassword: !Ref DBPassword DBClusterIdentifier: !Sub cromwell-${Namespace} BackupRetentionPeriod: 7 DatabaseName: cromwell Engine: aurora EngineMode: serverless EnableHttpEndpoint: true DBSubnetGroupName: !Ref DBSubnetGroup ScalingConfiguration: AutoPause: true MinCapacity: 1 MaxCapacity: 64 SecondsUntilAutoPause: 1000 StorageEncrypted: true VpcSecurityGroupIds: [!GetAtt RDSSecurityGroup.GroupId] Tags: - Key: architecture Value: !FindInMap ["TagMap", "default", "architecture"] - Key: solution Value: !FindInMap ["TagMap", "default", "solution"] ParamOrchestrator: Type: "AWS::SSM::Parameter" Properties: Name: !Sub /gwfcore/${GWFCoreNamespace}/orchestrator Type: String Value: "cromwell" Description: GWFCore orchestartor name Outputs: CromwellVersion: Description: Version of Cromwell installed. Value: Fn::If: - UseCromwellJar - !Ref CromwellJarUrl - Fn::If: - GetLatestCromwellVersion - !Ref CromwellVersion - !Ref CromwellVersionSpecified EC2Instance: Description: The EC2 Instance ID of your Cromwell Server Value: !Ref EC2Instance PublicIp: Value: !GetAtt EC2Instance.PublicIp Description: Cromwell server public IP address HostName: Value: !GetAtt EC2Instance.PublicDnsName Description: Cromwell server public DNS name CloudWatchLogStream: Value: Fn::Join: - "/" - - !Sub https://${AWS::Region}.console.aws.amazon.com - !Sub cloudwatch/home?region=${AWS::Region}#logsV2:log-groups - !Sub log-group/cromwell-server/log-events/${EC2Instance} Description: Cromwell server log stream