Skip to content
This repository was archived by the owner on Apr 13, 2023. It is now read-only.

Commit 18b03a7

Browse files
authored
Add Troubleshooting Section to Install.md (#89)
* Add troubleshooting section in install.md. Handles invalid cloudformation template issue. * Move Optional Configuration to bottom of README below Manual Installation. The Optional Configuration instructions is relevant when doing a Manual Installation
1 parent 41131ac commit 18b03a7

File tree

1 file changed

+145
-146
lines changed

1 file changed

+145
-146
lines changed

Diff for: INSTALL.md

+145-146
Original file line numberDiff line numberDiff line change
@@ -121,138 +121,6 @@ container_id=$(docker ps -f "label=install-container" --format "{{.ID}}")
121121
docker rm ${container_id}
122122
```
123123

124-
### Optional installation configurations
125-
126-
#### Elasticsearch Kibana server
127-
128-
The Kibana server allows you to explore data inside your Elasticsearch instance through a web UI. This server is automatically created if 'stage' is set to `dev`.
129-
130-
Accessing the Kibana server requires you to set up a Cognito user. The installation script can help you set up a Cognito user, or you can do it manually through the AWS Cognito Console.
131-
132-
The installation script will print the URL to the Kibana server after setup completes. Navigate to this URL and enter your login credentials to access the Kibana server.
133-
134-
If you lose this URL, it can be found in the `INFO_OUTPUT.yml` file under the "ElasticsearchDomainKibanaEndpoint" entry.
135-
136-
##### Accessing Elasticsearch Kibana server
137-
138-
> NOTE: Kibana is only deployed in the default 'dev' stage; if you want Kibana set up in other stages, like 'production', please remove `Condition: isDev` from [elasticsearch.yaml](./cloudformation/elasticsearch.yaml)
139-
140-
The Kibana server allows you to explore data inside your Elasticsearch instance through a web UI.
141-
142-
In order to be able to access the Kibana server for your Elasticsearch Service Instance, you need to create and confirm a Cognito user. Run the below command or create a user from the Cognito console.
143-
144-
```sh
145-
# Find ELASTIC_SEARCH_KIBANA_USER_POOL_APP_CLIENT_ID in the printout
146-
serverless info --verbose
147-
148-
# Create new user
149-
aws cognito-idp sign-up \
150-
--region <REGION> \
151-
--client-id <ELASTIC_SEARCH_KIBANA_USER_POOL_APP_CLIENT_ID> \
152-
--username <[email protected]> \
153-
--password <TEMP_PASSWORD> \
154-
--user-attributes Name="email",Value="<[email protected]>"
155-
156-
# Find ELASTIC_SEARCH_KIBANA_USER_POOL_ID in the printout
157-
# Notice this is a different ID from the one used in the last step
158-
serverless info --verbose
159-
160-
# Confirm new user
161-
aws cognito-idp admin-confirm-sign-up \
162-
--user-pool-id <ELASTIC_SEARCH_KIBANA_USER_POOL_ID> \
163-
--username <[email protected]> \
164-
--region <REGION>
165-
166-
# Example
167-
aws cognito-idp sign-up \
168-
--region us-west-2 \
169-
--client-id 4rcsm4o7lnmb3aoc2h64nv1324 \
170-
--username [email protected] \
171-
--password Passw0rd! \
172-
--user-attributes Name="email",Value="[email protected]"
173-
174-
aws cognito-idp admin-confirm-sign-up \
175-
--user-pool-id us-west-2_sOmeStRing \
176-
--username [email protected] \
177-
--region us-west-2
178-
```
179-
180-
###### Get Kibana url
181-
182-
After the Cognito user is created and confirmed you can now log in with the username and password, at the ELASTIC_SEARCH_DOMAIN_KIBANA_ENDPOINT (found with the `serverless info --verbose` command). **Note** Kibana will be empty at first and have no indices, they will be created once the FHIR server writes resources to the DynamoDB
183-
184-
#### DynamoDB table backups
185-
186-
Daily DynamoDB Table back-ups can be optionally deployed via an additional 'fhir-server-backups' stack. The installation script will deploy this stack automatically if indicated during installation.
187-
188-
The reason behind multiple stacks is that backup vaults can be deleted only if they are empty, and you can't delete a stack that includes backup vaults if they contain any recovery points. With separate stacks it is easier for you to operate.
189-
190-
These back-ups work by using tags. In the [serverless.yaml](./serverless.yaml) you can see ResourceDynamoDBTable has a `backup - daily` & `service - fhir` tag. Anything with these tags will be backed-up daily at 5:00 UTC.
191-
192-
To deploy the stack and start daily backups (outside of the install script):
193-
194-
```sh
195-
aws cloudformation create-stack --stack-name fhir-server-backups --template-body file://<file location of backup.yaml> --capabilities CAPABILITY_NAMED_IAM
196-
# Example
197-
aws cloudformation create-stack --stack-name fhir-server-backups --template-body file:///mnt/c/ws/src/fhir-works-on-aws-deployment/cloudformation/backup.yaml --capabilities CAPABILITY_NAMED_IAM
198-
```
199-
200-
#### Audit log mover
201-
202-
Audit Logs are placed into CloudWatch Logs at <CLOUDWATCH_EXECUTION_LOG_GROUP>. The Audit Logs includes information about request/responses coming to/from your API Gateway. It also includes the Cognito user that made the request.
203-
204-
In addition, if you would like to archive logs older than 7 days into S3 and delete those logs from Cloudwatch Logs, please follow the instructions below.
205-
206-
From the root directory
207-
208-
```sh
209-
cd auditLogMover
210-
serverless deploy --aws-profile <AWS PROFILE> --stage <STAGE> --region <AWS_REGION>
211-
```
212-
213-
#### Adding encryption to S3 bucket policy (Optional)
214-
215-
To encrypt all objects being stored in the S3 bucket as Binary resources, add the following yaml to the Resources' bucket policy:
216-
217-
```yaml
218-
ForceEncryption:
219-
Type: AWS::S3::BucketPolicy
220-
DependsOn: FHIRBinaryBucket
221-
Properties:
222-
Bucket: !Ref FHIRBinaryBucket
223-
PolicyDocument:
224-
Version: '2012-10-17'
225-
Statement:
226-
- Sid: DenyUnEncryptedObjectUploads
227-
Effect: Deny
228-
Principal: ''
229-
Action:
230-
- s3:PutObject
231-
Resource:
232-
- !Join ['', ['arn:aws:s3:::', !Ref FHIRBinaryBucket, '/']]
233-
Condition:
234-
'Null':
235-
's3:x-amz-server-side-encryption': true
236-
- Sid: DenyIncorrectEncryptionHeader
237-
Effect: Deny
238-
Principal: ''
239-
Action:
240-
- s3:PutObject
241-
Resource:
242-
- !Join ['', ['arn:aws:s3:::', !Ref FHIRBinaryBucket, '/']]
243-
Condition:
244-
StringNotEquals:
245-
's3:x-amz-server-side-encryption': 'aws:kms'
246-
```
247-
248-
##### Making requests to S3 buckets with added encryption policy
249-
250-
S3 bucket policies can only examine request headers. When we set the encryption parameters in the getSignedUrlPromise those parameters are added to the URL, not the HEADER. Therefore the bucket policy would block the request with encryption parameters in the URL. The workaround to add this bucket policy to the S3 bucket is have your client add the headers to the request as in the following example:
251-
252-
```sh
253-
curl -v -T ${S3_UPLOAD_FILE} ${S3_PUT_URL} -H "x-amz-server-side-encryption: ${S3_SSEC_ALGORITHM}" -H "x-amz-server-side-encryption-aws-kms-key-id: ${KMS_SSEC_KEY}"
254-
```
255-
256124
### Known installation issues
257125

258126
- Installation can fail if your computer already possesses an installation of Python 3 earlier than version 3.3.x.
@@ -406,20 +274,6 @@ From the command’s output note down the following data
406274
- CLOUDWATCH_EXECUTION_LOG_GROUP
407275
- from Stack Outputs: CloudwatchExecutionLogGroup:
408276

409-
### Deploying audit log mover
410-
411-
Audit Logs are placed into CloudWatch Logs at <CLOUDWATCH_EXECUTION_LOG_GROUP>. The Audit Logs includes information about request/responses coming to/from your API Gateway. It also includes the Cognito user that made the request.
412-
413-
In addition, if you would like to archive logs older than 7 days into S3 and delete those logs from Cloudwatch Logs, please follow the instructions below.
414-
415-
From the root directory
416-
417-
```$sh
418-
cd auditLogMover
419-
yarn install
420-
serverless deploy --aws-profile <AWS PROFILE> --stage <STAGE> --region <AWS_REGION>
421-
```
422-
423277
### Initialize Cognito
424278

425279
Initially, AWS Cognito is set up supporting OAuth2 requests in order to support authentication and authorization. When first created there will be no users. This step creates a `workshopuser` and assigns the user to the `practitioner` User Group.
@@ -463,3 +317,148 @@ ACCESS_KEY=<ACCESS_KEY> SECRET_KEY=<SECRET_KEY> ES_DOMAIN_ENDPOINT=<ES_DOMAIN_EN
463317
```
464318

465319
These parameters can be found by checking the `INFO_OUTPUT.yml` file generated by the installation script, or by running the previously mentioned `serverless info --verbose` command.
320+
321+
### Optional installation configurations
322+
323+
#### Elasticsearch Kibana server
324+
325+
The Kibana server allows you to explore data inside your Elasticsearch instance through a web UI. This server is automatically created if 'stage' is set to `dev`.
326+
327+
Accessing the Kibana server requires you to set up a Cognito user. The installation script can help you set up a Cognito user, or you can do it manually through the AWS Cognito Console.
328+
329+
The installation script will print the URL to the Kibana server after setup completes. Navigate to this URL and enter your login credentials to access the Kibana server.
330+
331+
If you lose this URL, it can be found in the `INFO_OUTPUT.yml` file under the "ElasticsearchDomainKibanaEndpoint" entry.
332+
333+
##### Accessing Elasticsearch Kibana server
334+
335+
> NOTE: Kibana is only deployed in the default 'dev' stage; if you want Kibana set up in other stages, like 'production', please remove `Condition: isDev` from [elasticsearch.yaml](./cloudformation/elasticsearch.yaml)
336+
337+
The Kibana server allows you to explore data inside your Elasticsearch instance through a web UI.
338+
339+
In order to be able to access the Kibana server for your Elasticsearch Service Instance, you need to create and confirm a Cognito user. Run the below command or create a user from the Cognito console.
340+
341+
```sh
342+
# Find ELASTIC_SEARCH_KIBANA_USER_POOL_APP_CLIENT_ID in the printout
343+
serverless info --verbose
344+
345+
# Create new user
346+
aws cognito-idp sign-up \
347+
--region <REGION> \
348+
--client-id <ELASTIC_SEARCH_KIBANA_USER_POOL_APP_CLIENT_ID> \
349+
--username <[email protected]> \
350+
--password <TEMP_PASSWORD> \
351+
--user-attributes Name="email",Value="<[email protected]>"
352+
353+
# Find ELASTIC_SEARCH_KIBANA_USER_POOL_ID in the printout
354+
# Notice this is a different ID from the one used in the last step
355+
serverless info --verbose
356+
357+
# Confirm new user
358+
aws cognito-idp admin-confirm-sign-up \
359+
--user-pool-id <ELASTIC_SEARCH_KIBANA_USER_POOL_ID> \
360+
--username <[email protected]> \
361+
--region <REGION>
362+
363+
# Example
364+
aws cognito-idp sign-up \
365+
--region us-west-2 \
366+
--client-id 4rcsm4o7lnmb3aoc2h64nv1324 \
367+
--username [email protected] \
368+
--password Passw0rd! \
369+
--user-attributes Name="email",Value="[email protected]"
370+
371+
aws cognito-idp admin-confirm-sign-up \
372+
--user-pool-id us-west-2_sOmeStRing \
373+
--username [email protected] \
374+
--region us-west-2
375+
```
376+
377+
###### Get Kibana url
378+
379+
After the Cognito user is created and confirmed you can now log in with the username and password, at the ELASTIC_SEARCH_DOMAIN_KIBANA_ENDPOINT (found with the `serverless info --verbose` command). **Note** Kibana will be empty at first and have no indices, they will be created once the FHIR server writes resources to the DynamoDB
380+
381+
#### DynamoDB table backups
382+
383+
Daily DynamoDB Table back-ups can be optionally deployed via an additional 'fhir-server-backups' stack. The installation script will deploy this stack automatically if indicated during installation.
384+
385+
The reason behind multiple stacks is that backup vaults can be deleted only if they are empty, and you can't delete a stack that includes backup vaults if they contain any recovery points. With separate stacks it is easier for you to operate.
386+
387+
These back-ups work by using tags. In the [serverless.yaml](./serverless.yaml) you can see ResourceDynamoDBTable has a `backup - daily` & `service - fhir` tag. Anything with these tags will be backed-up daily at 5:00 UTC.
388+
389+
To deploy the stack and start daily backups (outside of the install script):
390+
391+
```sh
392+
aws cloudformation create-stack --stack-name fhir-server-backups --template-body file://<file location of backup.yaml> --capabilities CAPABILITY_NAMED_IAM
393+
# Example
394+
aws cloudformation create-stack --stack-name fhir-server-backups --template-body file:///mnt/c/ws/src/fhir-works-on-aws-deployment/cloudformation/backup.yaml --capabilities CAPABILITY_NAMED_IAM
395+
```
396+
397+
#### Audit log mover
398+
399+
Audit Logs are placed into CloudWatch Logs at <CLOUDWATCH_EXECUTION_LOG_GROUP>. The Audit Logs includes information about request/responses coming to/from your API Gateway. It also includes the Cognito user that made the request.
400+
401+
In addition, if you would like to archive logs older than 7 days into S3 and delete those logs from Cloudwatch Logs, please follow the instructions below.
402+
403+
From the root directory
404+
405+
```sh
406+
cd auditLogMover
407+
yarn install
408+
serverless deploy --aws-profile <AWS PROFILE> --stage <STAGE> --region <AWS_REGION>
409+
```
410+
411+
#### Adding encryption to S3 bucket policy (Optional)
412+
413+
To encrypt all objects being stored in the S3 bucket as Binary resources, add the following yaml to the Resources' bucket policy:
414+
415+
```yaml
416+
ForceEncryption:
417+
Type: AWS::S3::BucketPolicy
418+
DependsOn: FHIRBinaryBucket
419+
Properties:
420+
Bucket: !Ref FHIRBinaryBucket
421+
PolicyDocument:
422+
Version: '2012-10-17'
423+
Statement:
424+
- Sid: DenyUnEncryptedObjectUploads
425+
Effect: Deny
426+
Principal: ''
427+
Action:
428+
- s3:PutObject
429+
Resource:
430+
- !Join ['', ['arn:aws:s3:::', !Ref FHIRBinaryBucket, '/']]
431+
Condition:
432+
'Null':
433+
's3:x-amz-server-side-encryption': true
434+
- Sid: DenyIncorrectEncryptionHeader
435+
Effect: Deny
436+
Principal: ''
437+
Action:
438+
- s3:PutObject
439+
Resource:
440+
- !Join ['', ['arn:aws:s3:::', !Ref FHIRBinaryBucket, '/']]
441+
Condition:
442+
StringNotEquals:
443+
's3:x-amz-server-side-encryption': 'aws:kms'
444+
```
445+
446+
##### Making requests to S3 buckets with added encryption policy
447+
448+
S3 bucket policies can only examine request headers. When we set the encryption parameters in the getSignedUrlPromise those parameters are added to the URL, not the HEADER. Therefore the bucket policy would block the request with encryption parameters in the URL. The workaround to add this bucket policy to the S3 bucket is have your client add the headers to the request as in the following example:
449+
450+
```sh
451+
curl -v -T ${S3_UPLOAD_FILE} ${S3_PUT_URL} -H "x-amz-server-side-encryption: ${S3_SSEC_ALGORITHM}" -H "x-amz-server-side-encryption-aws-kms-key-id: ${KMS_SSEC_KEY}"
452+
```
453+
### Troubleshooting
454+
- During installation if you encounter this error
455+
456+
`An error occurred: DynamodbKMSKey - Exception=[class software.amazon.awssdk.services.kms.model.MalformedPolicyDocumentException] ErrorCode=[MalformedPolicyDocumentException], ErrorMessage=[Policy contains a statement with one or more invalid principals.]`
457+
458+
Then serverless has generated an invalid Cloudformation template.
459+
1. Check that `serverless_config.json` has the correct `IAMUserArn`. You can get the arn by running `$(aws sts get-caller-identity --query "Arn" --output text)`
460+
2. Go to your AWS account and delete the `fhir-service-<stage>` Cloudformation template if it exist.
461+
3. Run `sudo ./scripts/install.sh` again
462+
463+
If you still get the same error after following the steps above, try removing the `fhir-works-on-aws-deployment` repository and downloading it again. Then proceed from step 2.
464+

0 commit comments

Comments
 (0)