This repo holds the CloudFormation stacks used for deployment and development of
- LARA
- Portal
- Log Ingester
- api.concord.org
- Question Rater
LARA Deployment (if you have access)
Running script to create an app-only Portal stack with parameters copied from another stack:
cd scripts
npm install
cp create-config.sample.yml create-config.yml
# modify create-config.yml to match what you want to do
npm run create-stack
This script should work for other types of stacks, but it hasn't been tested.
See the file ./scripts/README.md for more details.
See also the Google Drive document for a verbose blow-by-blow account of how this was used to setup a staging environment in the past.
These instructions should help you deploy paired sets of LARA & Portal servers. The examples assume the QA environment, but you can do this in staging as well. Recent template changes should make this process easier.
Summary:
- Clone RDS instances of the production LARA and Portal databases using snapshots if you can.
- Use
create-stack
scripts to provision a Portal using configs and param overrides. - Modify the Portal auth-client
authoring
configuration to fix authentication. - Update URLS to shared resources on both servers using
lib/script/rewrite_lara_portal_resources.rb
from the LARA repo.
-
Change into the
scripts
directory and install the dependencies:cd scripts && npm install
-
Create some configuration files. These config templates will setup your stacks for you. See the
README.md
file in the scripts directory for more info:cp configs/create-config.sample.yml configs/create-my-project-config.yml
-
Copy Parameters from production or staging stacks.
- Select your primary AWS account credentials to copy stack parameters for the production LARA and Portal instances you are working on.
export AWS_PROFILE=concord
- Run the
create-stack
npm script to copy the stack parameters your want.npm run create-stack
- Select your primary AWS account credentials to copy stack parameters for the production LARA and Portal instances you are working on.
-
Select the first menu item "Save stack params". The script will show you a list of running stacks. Type-ahead search for the stack you want to copy into the QA environment.
-
Your parameters will be saved in the folder
stack-params
-
Modify your
configs/create-my-project-config.yml file
- Update the
OriginalStack
parameter to point to the stack-params file you just downloaded. - Update any
ParameterModifications
you would like to override.- Check or override these LARA params:
HostName
DomainNameBase
CloudWatchLogGroup
DbHost
DatabaseSecurityGroupId
Environment
QAPortalSecret
QAPortalURL
- Check or override these PORTAL params:
ShortName
DomainName
CloudWatchLogGroup
SiteURL
Environment
DbHost
DatabaseSecurityGroupId
AuthoringSiteURL
S3SecreteAccessKey
S3AccessKeyId
ReportDomainName
LogStashDbHost
ClusterStackName
- Check or override these LARA params:
- See the
scripts/README.md
file for more info
- Update the
-
Configure AWS command line tools. Set your
AWS_PROFILE
to the appropriate account (eg:concord-qa
) -
Run the
create-stack
npm script again. -
Select
Create stack
from the script menu, selecting your newly modified configuration file (create-my-project-config.yml
) -
Monitor the creation of your stack using the AWS console.
-
Before creating the LARA instance, connect to the Portal you created.
-
Find the AuthClient for
authoring
in the admin clients listing in the Portal, and edit it. -
Generate a new Secret.
-
Update the
Allowed redirect URIs
parameter to include the callback URL for your future LARA instance eg: -
- https://ngss-staging-lara.staging.concord.org/users/auth/cc_portal_qa_portal/callback
-
Set the Template parameters for the LARA instance:
PortalClientID: 'authoring'
QAPortalSecret: <secret from Portal auth-clients>
QAPortalURL: <https url to the Portal>
-
If the
QAPortalSecret
andQAPortalURL
parameters are set in thecreate-config.yml
file, thelara-ecs.yml
template will configure a newCONCORD_CONFIGURED_PORTALS
auth provider. -
Check or set the value for the parameter
PortalClientID
-
Make sure
PortalClientID
,QAPortalURL
andQAPortalSecret
match an entry in the list of Auth Clients on the paired Portal.
Because the RDS servers were created from production, its important to rewrite resources in both the Portal and in LARA.
- Copy the script from the lara git repo in
lib/script/ rewrite_lara_portal_resources.rb
and open a consoles in both the LARA and Portal rails servers. - In the Portal console run eg:
update_portal_lara_refs('authoring.concord.org', 'my-lara.concord-qa.org')
- In Lara console run eg:
update_lara_portal_refs('learn.concord.org', 'my-portal.concord-qa.org')
This domain is managed by the api.concord.org.yml CloudFormation template. That template creates the domain within the AWS API Gateway service and adds a Route 53 recordset pointing to the CloudFront distribution automatically created as part of the API Gateway domain.
Other CloudFormation templates using Lambda functions can then route requests via api.concord.org by using a AWS::ApiGateway::BasePathMapping
in the following form (taken frm log-ingester.yml):
ApiGatewayMapping:
Type: AWS::ApiGateway::BasePathMapping
DependsOn:
- ApiGateway
Properties:
BasePath: !Ref ApiGatewayBasePath
DomainName: api.concord.org
RestApiId: !Ref ApiGateway
Stage: latest
where ApiGatewayBasePath
is a CloudFormation parameter and ApiGateway
is a AWS::ApiGateway::RestApi
. If, for example, ApiGatewayBasePath
is log-staging
and the endpoint url of the latest
stage ApiGateway is https://k254j5v1p0.execute-api.us-east-1.amazonaws.com/latest/
then after the gateway mapping completes https://api.concord.org/log-staging/logs
will route to https://k254j5v1p0.execute-api.us-east-1.amazonaws.com/log-staging/logs
.
The log-ingester.yml CloudFormation template creates the following resources (along with the needed roles)
- An API Gateway
- A Kinesis stream
- A Lambda function
- An RDS database
The API Gateway takes POST logging requests to /logs and, via template mapping, and sends a record to the Kinesis stream in the form of ;. The Kinesis stream automatically triggers the Lambda function which parses the record and then creates a canonical log record that is inserted into the RDS database into the logs table.
This ingester is meant to replace the Heroku based log manager.
If you do not import the existing log manager data from Heroku the ingester schema needs to be manually created by connecting to the RDS instance that is created and then running the following queries:
CREATE EXTENSION IF NOT EXISTS hstore;
CREATE TABLE logs (
id integer NOT NULL,
session character varying(255),
username character varying(255),
application character varying(255),
activity character varying(255),
event character varying(255),
"time" timestamp without time zone,
parameters hstore DEFAULT ''::hstore NOT NULL,
extras hstore DEFAULT ''::hstore NOT NULL,
created_at timestamp without time zone,
updated_at timestamp without time zone,
event_value character varying(255),
run_remote_endpoint character varying(255)
);
CREATE SEQUENCE logs_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE ONLY logs ALTER COLUMN id SET DEFAULT nextval('logs_id_seq'::regclass);
ALTER TABLE ONLY logs ADD CONSTRAINT logs_pkey PRIMARY KEY (id);
CREATE INDEX index_logs_on_activity ON logs USING btree (activity);
CREATE INDEX index_logs_on_application ON logs USING btree (application);
CREATE INDEX index_logs_on_event ON logs USING btree (event);
CREATE INDEX index_logs_on_run_remote_endpoint ON logs USING btree (run_remote_endpoint) WHERE (run_remote_endpoint IS NOT NULL);
CREATE INDEX index_logs_on_session ON logs USING btree (session);
CREATE INDEX index_logs_on_time ON logs USING btree ("time");
CREATE INDEX index_logs_on_username ON logs USING btree (username);
You can locally validate the CloudFormation templates in two ways:
- Use cfn-lint
- Run
pip install cfn-lint
to install it - Run
cfn-lint <filename>
to lint the file specified
- Run
- Use aws cloudformation validate-template
- Install the aws cli
- Run
aws cloudformation validate-template --template-body file://<filename>
to validate the file specified