Visitar URL original
site-scanning-engine/docs/environment_provisioning.md at main · GSA/site-scanning-engine · GitHub
Skip to content

Latest commit

 

History

History
160 lines (119 loc) · 6.21 KB

environment_provisioning.md

File metadata and controls

160 lines (119 loc) · 6.21 KB

Environment Provisioning

Overview

Deploying to an environment (space) requires that the space exist -- be provisionied -- before code can be deployed to it. The steps to provision an environment include:

  1. Create the space on Cloud Foundry
  2. Create vars file for the environment
  3. Target the space on Cloud Foundry
  4. Create an API key for use with the environment
  5. Provision required services and deploy the application
  6. Test the new environment
  7. Verify that the service accounts can deploy to the environment

Detailed Instructions

1. Create the space on Cloud Foundry

First, verify that the environment you wish to create doesn't yet exist by using the cf spaces command (note: you must be logged in first).

Assuming the space does not yet exist, use the cf create-space command to create the space:

cf create-space NAME_OF_SPACE -o NAME_OF_ORG

Note: NAME_OF_ORG is the name of the organization in Cloud Foundry and NAME_OF_SPACE is the name of the space (environment) to be used.

2. Create vars file for the environment

Cloud Foundry uses manifest.yml files to describe the applications to be deployed to a space. The manifest.yml file for this project uses variable substitution to specify environment-specific variables (e.g., memory quota, number of instances, etc.). The values for these variables are found in the env-NAME_OF_SPACE.yml files. So, for example, the vars file for the dev environment is vars-dev.yml (case-sensitive).

So, to create a vars file for a new environment, copy an existing vars file and supply the appropriate values. Be sure to add the file to the repository (git add), commit it (git commit) and push it (git push origin NAME_OF_BRANCH) so that the deployment script is able to deploy changes to said environment.

3. Target the space on Cloud Foundry

The deployment script -- used to provision the environment -- uses the name of the space in order to select which vars file will be used with the environment. Therefore, it's important to target the space by using the cf target command:

cf target -o NAME_OF_ORG -s NAME_OF_SPACE

4. Create an API key for use with the environment

The deployment script requests the API_KEY to use with the deployed environment. This API_KEY is passed along with API calls to authenticate the request.

The API key is stored as a user-provided service, so its value is accessible via cf env. Moreover, the only time that the key is needed is when connecting the API to an external service (e.g., API Umbrella) or when querying the API directly (e.g., via curl).

As a result, the value generally doesn't matter, particularly as an authorized agent may query Cloud Foundry to retrieve the value.

That is, it could literally be a face-plant on the keyboard.

5. Provision required services and deploy the application

There is no longer a single deployment script that provisions a new environment. Instead, the services listed under services: in manifest.yml (e.g., RDS Postgres, Redis, the API key, etc.) must be created in the space -- with cf create-service and cf create-user-provided-service -- before the application can be deployed.

The message queue must be created with an explicit engine and version. Without them, the broker defaults to Redis 7.1 rather than Valkey 8.2, the engine this project targets:

cf create-service aws-elasticache-redis redis-3node scanner-message-queue \
  -c '{"engine": "valkey", "engine_version": "8.2"}'

The version must be a quoted string. Note the parameter key is engine_version (snake_case) -- the cloud.gov ElastiCache docs show engineVersion (camelCase), but the deployed aws-broker only recognizes engine_version; the camelCase key is silently ignored and the plan's default version (7.1) is used instead, which fails outright for the valkey engine since it has no 7.1 release.

For the API key service, if there is no value for the API_KEY user-provided service, supply one when creating it. Provide the value previously discussed (or slap the keyboard a few times).

Once the required services exist, the application is deployed via the GitHub Actions workflows described in Deployment (e.g., dev.yml or deploy.yml) -- a new space will need its own workflow (or an update to an existing one) pointing at the new space and vars file.

Note: the process of creating and binding all of the services to the (new) applications takes a while -- don't be surprised if it takes upwards of 15..20 minutes to complete. This is normal.

6. Verify that the service accounts can deploy to the environment

Once the application is provisioned, you, dear operator, should probably add the service accounts used to deploy other environments to this application. One way to accomplish this is by listing the users who have access to other, existing spaces:

cf space-users NAME_OF_ORG NAME_OF_SPACE

To add a user to the new space:

cf set-space-role NAME_OF_USER NAME_OF_ORG NAME_OF_SPACE NAME_OF_ROLE

Here, NAME_OF_USER is the user's name and NAME_OF_ROLE is the name of the role to apply (e.g., SpaceDeveloper)

Note: usernames for service accounts are typically strings of 36 characters consisting of numbers, letters, and dashes.

7. Test the new environment

A running deployment may be tested from the command line with the curl command provided the API key (described previously) is passed in the X-Secret-Api-Access-Token HTTP header.

In the following example, the following variables are used:

  • key: the API key (available from cf env)
  • route: the route (hostname, available from cf app)
  • endpoint: the endpoint to query (e.g., /websites/)
curl -H "X-Secret-Api-Access-Token: $key" "https://${route}${endpoint}"

Alternatively, one may use the provided site_scanner_endpoint_test.bash script to automate the fetching of the application's route, API key, etc.