mira
Version:
NearForm Accelerator for Cloud Native Serverless AWS
127 lines (98 loc) • 4.43 kB
Markdown
# Continuous Integration
See also [CI/CD Quickstart Guide](../quick-start/README.md#continuous-integration).
## CI/CD Architecture
Mira utilizes cloud-native services for the delivery pipeline.
Key AWS Services used:
* [AWS CodePipeline](https://aws.amazon.com/codepipeline/getting-started/)
* [AWS CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/getting-started.html)
* [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/getting-started-cc.html)
AWS CodePipeline is used for overall orchestration of the delivery pipeline. It is capable of detecting changes in the
CodeCommit repository and triggers when required. A single CodePipeline is defined for delivery, with the pipeline itself built from one or more stages of pre-configured actions.
For code deployment, Mira uses AWS CodeBuild which a dedicated service for artifacts build up and optionally deployment.
Behind the scenes CodeBuild triggers the same Mira commands as a Developer from local workstation.
In order to provide permissions for CodeBuild to deploy stacks, Mira provision dedicated Role(s) in predefined accounts.
Mira CI/CD can deploy the code into the same AWS account where it is hosted, but also to different accounts as required.
You define deployment stages by configuring the `cicd.accounts` value in the `config/default.json` file.
A typical pipeline would look like this:
`Source -> Test -> Manual Approval -> Staging -> Manual Approval -> Production`
For more information on available configuration options see [config documentation](../config/README.md).
__Note:__ CI/CD assumes [github actions](https://github.com/features/actions) are used for code mirroring into AWS CodeCommit. See the `.github` directory for more information.
Otherwise, the developer is responsible for mirroring the code into the dedicated AWS CodeCommit or use AWS CodeCommit directly.
## Deploy Role
CodeBuild runs with an internal role generated by the pipeline. However, Mira needs to assume a specific role with all the permissions for the app.
To do this, create a `DeploymentPermissions` subclass in your app like the following:
```
import { DeploymentPermissions, MiraApp } from '/mira'
export default class CustomPermissions extends DeploymentPermissions {
constructor(parent: Construct) {
super(parent)
const account = MiraConfig.getEnvironment()
const baseProject = MiraApp.getBaseStackName()
this.role.addToPolicy(new PolicyStatement({
actions: [
's3:CreateBucket',
...
],
resources: [
`arn:aws:s3:::${baseProject.toLowerCase()}-*`
]
}))
this.role.addToPolicy(new PolicyStatement({
actions: [
'iam:CreateRole',
...
],
resources: [
`arn:aws:iam::${account.env.account}:role/${baseProject}-*`
]
}))
}
}
```
Then, modify your `cicd` section in the config file (`default.json`) and create/update property `permissionsFile` with the path to the previously created file, e.g.:
```
"cicd": {
"target": "cicd",
"buildspecFile": "infra/buildspec.yaml",
"permissionsFile": "infra/src/permissions.js",
"provider": "codecommit",
"repositoryUrl": "YOUR_REPOSITORY_URL",
"branchName": "master",
"codeCommitUserPublicKey": "ssh-rsa xxx",
"stages": [
{
"target": "staging",
"withDomain": false,
"requireManualApproval": false,
"privileged": true
},
{
"target": "production",
"withDomain": false,
"requireManualApproval": true,
"privileged": true
}
]
}
```
## Deploy Pipeline
You can deploy the pipeline with the following command:
```
npx mira cicd
```
For each `cicd.accounts` element in the configuration file, a deploy stage and stack with deployment permissions role is created.
For each value it's possible to specify a previous manual `Promote` action if `requireManualApproval: true`.
If you need variables or secrets or both available during your deploy phase, you can use `--envVar` as shown in the example below:
### Example
Deploy the pipeline with a variable and a secret as follows:
```
npx mira cicd --envVar SECRET_TOKEN=123456789 --envVar FOO=bar
```
Then, you can use the secret in `buildspec.yml` file as follows:
```
...
build:
commands:
- ./login-to-service.sh --token=${SECRET_TOKEN}
- npx mira deploy
```