# Getting started

### Deploy MySQL and Redis on AWS in less than 10 lines of code

Follow this simple guide to deploy a MySQL and a Redis instance on **your** AWS account. By the end of this guide, you'll have a MySQL instance running on RDS and a Redis cluster on Elasticache.What you'll need:

* An [AWS account](https://docs.aws.amazon.com/SetUp/latest/UserGuide/setup-AWSsignup.html) with the credentials stored in your local machine. You could create an AWS profile that uses those credentials and would make things easier. More details on the [official AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). If you already have an AWS account profile set up locally, you can skip this.
* [Terraform](https://www.terraform.io/) installed locally. You can follow the [official Terraform documentation](https://developer.hashicorp.com/terraform/install) to do that, or if you already have Terraform installed, feel free to skip this part.
* [NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to help us install stackmate.
* Your favorite text editor, terminal and a working internet connection.

Here's what you'll get after you've finished this guide:

* A [MySQL database](/configuration/database-services) instance on RDS, within the AWS free tier to help run in sane costs
* A [Redis instance](/configuration/cache-services) on Elasticache, within the AWS free tier
* A VPC and Internet Gateway to keep your database instances isolated and secure
* Your credentials securely stored on AWS Secrets Manager

{% hint style="info" %}
This guide is meant for the Community Edition of Stackmate which is free and open-source.\
\
We also offer a [Cloud edition](https://stackmate.io/cloud/) that sets up your AWS account for you and deploys every time you push a new commit. We offer a **trial of 7 days** and **no credit card** is required
{% endhint %}

### 1. Create a configuration file

First, we need to create a configuration file for stackmate, under its default location which is `.stackmate/config.yml`. You can start by copying the code specified in this [example file](https://github.com/stackmate-io/stackmate/blob/main/examples/db-redis.yml) on the [stackmate repository](https://github.com/stackmate-io/stackmate). Our configuration file would then look something like this:

```yaml
---
# Optional - by default stackmate uses AWS
# provider: aws

# Optional - by default stackmate deploys to eu-central-1
# region: eu-central-1

state:
  # 👇 This will store the state file in our local machine
  # and should be OUTSIDE your source code repository,
  # so that you make sure it NEVER GETS COMMITTED to git
  #
  # Alternatively, you can use an S3 bucket to store the state
  # you can find more information by the end of this guide
  workspaceDir: /Users/<myusername>/.stackmate-states/my-cool-project

environments:
  production:
    mysql-database:
      type: mysql
      # Note: Use the externalLinks attribute to allow a resource
      # that's not deployed by stackmate to access the database
      # externalLinks:
      #  - 1.2.3.4
    redis-cache:
      type: redis

```

**Quick note**: By default your resources are deployed in a [VPC,](https://aws.amazon.com/vpc/) meaning that they're isolated from the outside world but all resources deployed by Stackmate, can connect with each other. If you need to allow connections from a resource that's not deployed by Stackmate, consider adding the `externalLinks` attribute to the service as documented in the [common service options](/configuration/configuration-file/environments#common-service-options) section for `environments`.

### 2. Create the directory to store the Terraform state in

Terraform requires a [state](https://developer.hashicorp.com/terraform/language/state) file to be present, so that it knows what the desired state of your infrastructure will be every time. For the sake of this guide, we will be storing our state files locally, but at the end of this guide, we'll see how we can use an AWS S3 bucket to securely store our states in.

Please note that as described in [Output files](/guides/output-files#should-i-commit-the-files-that-are-generated-by-stackmate), we should **NEVER** commit our state to version control and this is why the directory is set outside our repository. Now let's go ahead and create the directory:

```bash
$ mkdir -p ~/.stackmate-states/my-cool-project
```

### 3. Pick an AWS profile to use

Use your favorite editor to view an existing, or add a new AWS profile on your AWS configuration. As an example, we'll be using an AWS profile named `stackmate-user`. More details on the [official AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html).

### 4. Run the deployment!

Let's now prefix the AWS profile to the [stackmate deploy](/commands/stackmate-deploy) command and we're ready to go!

```
AWS_PROFILE=stackmate-user npx @stackmate/stackmate deploy production
```

This will do the following:

* Install stackmate cli locally (if it's not available already)
* Load the AWS profile specified
* Set up our infrastructure on the AWS account specified.

You'll be getting output on your terminal regarding the progress and once it's done, you'll get the endpoints you can connect to. For example:

```bash
# ... more output here ...
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

Outputs:
aws_redis_eu_central_1_1_endpoint = "redis-cache-production.abcdefg.0001.euc1.cache.amazonaws.com"
aws_mysql_eu_central_1_1_endpoint = "mysql-database-production.abcdefg.eu-central-1.rds.amazonaws.com:3306"
```

Your infrastructure is now deployed and ready to be used!

### 5. Bonus points: Use an S3 bucket to store the state

Deploying your state on an S3 bucket, allows your team to access it centrally, makes sure it's always available and handles versioning and locking. The benefits and the process Terraform uses is described in this [documentation page](https://developer.hashicorp.com/terraform/language/settings/backends/s3).

To be able to use an S3 bucket in our stackmate configuration with locking, the following needs to exist in advance:

* An [S3 bucket](https://aws.amazon.com/s3/) with versioning and no public access
* A [DynamoDB](https://aws.amazon.com/dynamodb/) table to be used for locking

You can create these resources manually, as described in numerous tutorials (for example [this](https://dev.to/aws-builders/configure-a-remote-backend-with-aws-s3-and-dynamodb-state-locking-in-terraform-3jne) one) but if you're already familiar with Terraform, we have prepared a [terraform script](https://github.com/stackmate-io/stackmate/blob/main/utilities/create-s3-state/main.tf) for you that you can use to create the resources described above. Here's how:

```bash
# create a working directory
mkdir ~/stackmate-state-preparation
cd ~/stackmate-state-preparation

# download the script from GitHub
curl -O https://raw.githubusercontent.com/stackmate-io/stackmate/main/utilities/create-s3-state/main.tf

# Initialize terraform
terraform init

# Apply changes using your AWS profile
AWS_PROFILE=stackmate-user terraform apply

# You'll get prompts similar to the following ones, you can 
# var.aws_dynamodb_lock_table_name
#   Enter a value: stackmate-state-locking

# var.aws_s3_bucket_name
#  Enter a value: stackmate-terraform-states

# var.infrastructure_region
#  Enter a value: eu-central-1

# Do you want to perform these actions?
#  Terraform will perform the actions described above.
#  Only 'yes' will be accepted to approve.
#  Enter a value: yes

# Ouptut would look something like this:
# aws_dynamodb_table.terraform_state_lock: Creating...
# aws_s3_bucket.terraform_state: Creating...
# aws_s3_bucket.terraform_state: Creation complete after 3s [id=stackmate-terraform-states]
# aws_s3_bucket_versioning.terraform_state: Creating...
# aws_s3_bucket_versioning.terraform_state: Creation complete after 2s [id=stackmate-terraform-states]
# aws_dynamodb_table.terraform_state_lock: Creation complete after 8s [id=stackmate-state-locking]

# Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

# Outputs:

# state_bucket = "stackmate-terraform-states"
# lock_table = "stackmate-state-locking"

```

The directory we used and its contents should now be safe to delete

You can use the value in the "Outputs" sections above to configure stackmate:

```yaml
---
state:
  # Copy the values from the outputs above
  bucket: stackmate-terraform-states
  lockTable: stackmate-state-locking

environments:
  production:
    # ... the rest of our configuration ...

```

Our next deployments will store the state in S3 and the state will be locked in DynamoDB

{% hint style="info" %}
[Stackmate Cloud](https://stackmate.io/cloud/) creates the state bucket and lock table for you and handles AWS profiles automatically, once it securely access your AWS account. We offer a **trial of 7 days** and **no credit card** is required.
{% endhint %}

Next steps

* You can check out the additional configuration in [Database services configuration page](/configuration/database-services) or [Cache services configuration page](/configuration/cache-services) and update the service section on `.stackmate/config.yml` accordingly
* You can add more [services](broken://pages/qykrZFsipkRgIusWc93k) to your configuration
* You can add more [environments](/configuration/configuration-file/environments) to your project, for example a `staging` environment
* [Install](/guides/installation) `stackmate` globally to avoid using `npx @stackmate/stackmate`
* Tweet about [@stackmate](https://twitter.com/stackmate), raise an [issue](https://github.com/stackmate-io/stackmate/issues), or view our [roadmap](https://github.com/stackmate-io/stackmate/projects).


# What is stackmate

### What is Stackmate?

Stackmate is a free, open source tool that helps busy professionals deploy their cloud infrastructure without doing much. It abstracts and simplifies resource creation, modification and destruction in an intuitive way, by introducing a really simple configuration file.

The reasoning behind Stackmate is that most of the times, all developers want, is to simply deploy their application code, database, cache or object storage services, without having to read the manual or going through complex DevOps processes.

### Who is Stackmate for?

Stackmate was built with the busy developer in mind. It's for people who want to deploy an average traffic website, that depends on a database and a few complementary services, without spending a lifetime in complex consoles or developer tools.

### How does it work?

{% hint style="info" %}
Working with stackmate through the command line, requires a little bit of familiarity with AWS beforehand. If you don't feel comfortable managing your infrastructure with the command line tool, perhaps the [Cloud](https://stackmate.io/cloud/) version would be more interesting and easier to use. We offer a **trial of 7 days** and **no credit card** is required.
{% endhint %}

Stackmate uses an extremely simple configuration file either in JSON or YAML format. Before you read on, let us re-assure you that we are fully aware that people hate YAML with a burning passion and that's why we kept it very very **very** simple, by providing sane defaults for the services deployed.

After you create the configuration file, you may use the `deploy` command to provision your cloud resources on the cloud provider of choice (\* we currently only support AWS but there's more to come):

* Stackmate will build the [Terraform](https://www.terraform.io/) configuration for the selected environment (eg. `production`).
* The generated [Terraform](https://www.terraform.io/) configuration will be stored in the project's folder (for example under `stacks/production/main.tf.json`).
* You don't need to provide your AWS credentials in your configuration, you can use environment variables or an [AWS profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) stored on your `~/.aws/config` file.
* Stackmate will trigger CDKTF which will look for your system's Terraform executable to provision your cloud resources
* It will store the [Terraform State](https://www.terraform.io/language/state/remote) to the corresponding location as per your configuration.
* It will store random generated secrets to a secure remote location (for example AWS Secrets Manager) so that you can securely view and rotate them.

{% hint style="info" %}
Follow our [Getting started](/) guide to learn more!
{% endhint %}

Once your stack has successfully been deployed, any modifications you make on the configuration file, will be reflected on your cloud infrastructure the next time you re-run the `deploy` command and any resource deleted from the configuration, will also be destroyed once you re-deploy.

### An important note regarding manual modification

Same as Terraform (which is used under the hood), any manual modification on your Stackmate-managed resources, will be lost when you next deploy. For example, if your Stackmate configuration file declares a MySQL database which is deployed on AWS and has a size of `db.t3.micro` and you modify it to eg. `db.t3.large`, that modification will be lost when you next deploy, due to Terraform's declarative nature.


# Installation

{% hint style="info" %}
If you need to make stackmate instantly available to your team's workflow without having to install anything, perhaps you should check our [Cloud](https://stackmate.io/cloud/) version. We offer a **trial of 7 days** and **no credit card** is required.
{% endhint %}

Installing stackmate is a simple, straight forward process where all you need is an `npm` client such as `npm` itself or `yarn`

### Installation as a global package through NPM

You can install stackmate through NPM by using the following command:

```
npm install -g @stackmate/stackmate
```

### Installation as a global package through Yarn

Same for yarn:

```
yarn global add @stackmate/stackmate
```

### Direct usage through NPX

We recommend that you install stackmate globally, however if you don't want to or if you just wanna give it a quick spin, feel free to run the package directly through `npx` using the following command:

```
npx @stackmate/stackmate [preview / deploy ...] <environment> [...options]
```

{% hint style="info" %}
Throughout the course of this documentation, we will assume that the package is globally available in the system and we'll be using `stackmate` as our executable
{% endhint %}


# Output files

{% hint style="danger" %}
Please make sure you NEVER commit your terraform state file in your version control. Read more about what files you could or couldn't commit [on this section](#should-i-commit-the-files-that-are-generated-by-stackmate).
{% endhint %}

Stackmate generates configuration files when running any of its commands. Let's break them down and see what can be committed to source control and what not.

The default location would be right next to your configuration file, but you can specify a different directory when running the commands, for example:

```
npx @stackmate/stackmate -c myconfig.yml -d stackmate/
```

Assuming that you are deploying a simple web application, you can use `.stackmate` as a configuration directory that holds your `config.yml` configuration file and the generated stacks.

```
my-project
│   ...
├── .stackmate
│   └── config.yml
├── ...
└── index.html
```

### What files are generated by stackmate

When running any stackmate command, the following files get generated:

* **Project stacks** - Stackmate generates a set of JSON files, which are then used by Terraform to deploy your stacks. These are generated by CDKTF and further documentation can be found on [CDKTF's documentation](https://learn.hashicorp.com/tutorials/terraform/cdktf#how-it-works) page.
* **Terraform state files** - Whether we're storing our project's state locally or not, terraform will be creating a state file to use for subsequent deployments.
* **Terraform internal files** - When using stackmate, we run Terraform for you, which creates a set files used internally.

An example structure of the files created, is illustrated below:

```bash
my-project
│   ...
├── .stackmate
│   │   stacks/
│   │   └── production
│   │        ├── .terraform
│   │        │     ├── providers
│   │        │     └── terraform.tfstate
│   │        ├── .terraform.lock.hcl
│   │        ├── main.tf.json
│   │        └── plan # optionally, if you run stackmate preview
│   │         
│   └── config.yml
├── ...
└── index.html
```

### Should I commit the files that are generated by Stackmate?

The one thing to keep in mind is **NEVER, never, never, EVER** commit your state on your source control.

The reason for stressing this so much is that your Terraform state **contains sensitive information** about your infrastructure, which you don't want to fall into the wrong hands. Even if you're working solo, you should still **avoid committing** this file into source control because if for example your GitHub account gets compromised and your private repository is checked out, the attackers would also gain access to your entire infrastructure too.

One file you could consider committing to source control, is the `.terraform.lock.hcl` file, which is the dependency lock file for Terraform. This file is used by Terraform to download providers locally while running operations (for example the AWS provider) and it's practically forcing Terraform to use a specific provider version. Otherwise, Terraform uses the most recent provider version. You can learn more on this Terraform [documentation](https://developer.hashicorp.com/terraform/language/files/dependency-lock) page.

The rest of the files are up to you too but you could **have a look** on the file's contents first. For convenience, we have a list of files you could append to `.gitignore` :

```gitignore
# file: .gitignore
stacks/
*.tfstate
.terraform.lock.hcl
```

### Where does stackmate keep my secrets?

Stackmate doesn't know anything about your secrets. They're generated when you deploy a stage as random values and they're safely stored in your provider's credentials service (for example AWS secrets store)


# Configuration File

{% hint style="info" %}
[Stackmate Cloud](https://stackmate.io/cloud/) replaces the configuration file and command line with a simple to use interface and automatic deployments. We offer a **trial of 7 days** and **no credit card** is required.
{% endhint %}

Stackmate uses a really simple configuration file that describes your infrastructure and resides in your application's directory.  It is advised to store it along with your application's code and commit it in source control so that you can track your infrastructure's changes consistently.

The configuration file can be either a YAML or JSON file and examples are provided in the stackmate repository under the [examples](https://github.com/stackmate-io/stackmate/blob/main/examples) directory.

### Options

The stackmate configuration file is designed to be as simple and straight-forward as it gets. The following list summarizes the configuration attributes that you can apply and you can find more details in the corresponding sections.

* [`state`](/configuration/configuration-file/state) - *Required* - The state storage configuration. *Applies to all environments*
* [`environments`](/configuration/configuration-file/environments) - *Required* - The environments and list of services that are available
* [`provider`](/configuration/configuration-file/provider) - *Optional* - The default cloud provider for the services deployed (by default we're using `aws`)
* [`region`](/configuration/configuration-file/region) - *Optional* - The default region to deploy the services within (by default we're using `eu-central-1`)

### Configuration example

The following configuration file, will deploy two environments, `production` and `staging` and each will hold two AWS-managed services:&#x20;

* A MySQL database on RDS instance of `db.t3.medium` size and
* A Redis cache of `cache.t3.medium` size

The services will be provisioned with sane defaults and will be within the free tier

{% code title=".stackmate/config.yaml" %}

```yaml
provider: aws
region: eu-central-1

state:
  bucket: stackmate-sample-app-state-files

# It is implied that secrets are stored in AWS Secrets Manager
# since we're using AWS as our provider
environments:
  production:
    database:
      type: mysql
      size: db.t3.large
      storage: 30

    cache:
      type: redis
      size: cache.t3.large

  staging:
    database:
      type: mysql
      size: db.t3.micro
      storage: 10

    cache:
      type: redis
      size: cache.t3.micro
```

{% endcode %}


# state

{% hint style="info" %}
You can deploy the state bucket and lock table by using [these instructions](https://docs.stackmate.io/configuration/configuration-file/pages/JJcujEOUgnUnP5wehd2B#2.-create-the-state-bucket-and-dynamodb-lock-table).
{% endhint %}

The `state` configuration option, is an `Object` which defines where the [Terraform State](https://www.terraform.io/language/state) should be stored after each deployment.&#x20;

### Accepted values

#### AWS S3 Bucket

For storing the state on an AWS S3 bucket, you need to specify an object containing the following attributes:

* `bucket` - The name for the bucket to use. It should comply with the guidelines that AWS provides for naming a bucket.
* `lockTable` - The DynamoDB table to use for state locking. If you don't want to use state locking, feel free to leave this option out.
* `statePath` - *Optional* - The name of the Terraform state file to use. By default it's `stackmate.tfstate` and it should always end in `.tfstate`
* `provider` - *Optional* - It should be set to `aws`. *You don't have to specify this value if the root configuration option for `provider` is set to `aws`.*

### Examples

#### Storing your state on a private, encrypted AWS S3 bucket with state locking

```yaml
...
state:
  bucket: my-awesome-project-state-bucket
  lockTable: stackmate-state-lock
  # 👇 this is optional, by default it will be set to eg. production/stackmate.tfstate
  statePath: my-cool-project.tfstate
```


# environments

The `environments` configuration is the most important part of the stackmate configuration file, since it contains all of your environments and services that are related to it. The structure of the object is as follows:

```
environments:
  <stage name>:
    <service name>:
      ... service configuration ...
  <other stage name>:
    ....
```

As you can see, each environment is added as a key to the `environments` object and every service that should be deployed on every environment, should be a key to the corresponding environment.

### Common Service Options

Every service on a stackmate configuration, should have a unique name and can be described with the following attributes:

#### Required attributes

* `type` - The service's type. It should be one of the services available. Acceptable values are:&#x20;
  * `application`  - Configures an Application service, an application running on a container
  * `object-store` - Configures an [object store](/configuration/object-storage) service like AWS S3
  * `memcached` - Configures a managed [Memcached](/configuration/cache-services) cluster service (eg. AWS Elasticache)&#x20;
  * `mariadb` - Configures a managed [MariaDB](/configuration/database-services) instance (eg. MariaDB on AWS RDS)
  * `mysql` - Configures a managed [MySQL](/configuration/database-services) instance (eg. MySQL on AWS RDS)
  * `postgresql` - Configures a managed [PostgreSQL](/configuration/database-services) instance (eg. PostgreSQL on AWS RDS)
  * `redis` - Configures a managed [Redis](/configuration/cache-services) instance (eg. AWS Elasticache)

{% hint style="info" %}
You can find more information for each service-specific options, on the corresponding page
{% endhint %}

#### Optional attributes

* `region` - the region to deploy the service. If not provided, the default configuration for the project's [`region`](/configuration/configuration-file/region) is used.
* `links` - A list of services that are inter-connected. For example a `mysql` service could be linked to the `application` service in order to allow incoming connections from the `application` service.
* `externalLinks` - A list of IPs of resources not deployed by Stackmate, to allow outside connections from
* `profile` - A pre-made profile to use for the service. If not specified, the `default` profile is used for the service. You need to refer to every service separately in order to view the corresponding options available. You can browse the profiles available in our [repository](https://github.com/stackmate-io/stackmate/tree/main/src/services/providers/aws/profiles).
* `overrides` - An object with attributes to override the default profile with. Each service has its own profile and own overrides. You need to refer to every service separately in order to view the corresponding options available.

These configuration options are available across all services on stackmate, and each service may or may not provide additional attributes to be configured by.

### Available services

Stackmate supports the following services that you can use in your environments configuration:

* [Database Services](/configuration/database-services)
* [Cache Services](/configuration/cache-services)
* [Object storage](https://app.gitbook.com/o/1hvtqlSFUrlyNGJZFoLw/s/-MZRy1bgyIc6l7rYOrXd/~/changes/61/services/object-storage)

You can find all the available options for every service on the corresponding page

### Example

{% code title=".stackmate/config.yaml" %}

```yaml
provider: aws
region: eu-central-1
...
environments:
  production:    # the production stage
    mysqldb:        # a mysql database service
      type: mysql
      size: db.t3.2xlarge
      storage: 300
      # ....
    postgresqldb:   # a postgresql database service
      type: postgresql
      size: db.t3.2xlarge
      storage: 300
      # ...

  staging:        # the staging stage, copied from production but with lower specs
    mysqldb:
      type: mysql
      size: db.t3.micro
      storage: 10
      # ....
    postgresqldb:   # a postgresql database service
      type: postgresql
      size: db.t3.micro
      storage: 10
      # ...
```

{% endcode %}


# provider

The `provider` configuration option is the default cloud provider to use for services launched, state and secret storage unless specified otherwise. This practically means that the value you specify for the `provider` configuration option is the only one required across the configuration file, if you plan to use only one provider for everything: environments and state.

### Accepted values

Accepted cloud providers are:

* `aws` - Allows use of the AWS (Amazon Web Services) provider

*Note: We plan to support more cloud providers in the near future.*


# region

Same with the [`provider`](/configuration/configuration-file/provider) configuration option, the `region` acts as a default for services to be launched with stackmate. Specifying a `region` means every service deployed with stackmate uses that region as a default, which basically means that you don't have to specify it in the services themselves

### Accepted values

The values accepted for the `region` configuration attribute, depend on the value you specified for the `provider` attribute, meaning that the `region` should be one of the regions that the cloud provider you specified in the `provider` uses.

For reference, you can check out the regions every cloud provider uses:

* For the `aws` provider: <https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/>


# Application Services

Stackmate supports Docker container images deployment on managed container services, like [AWS ECS](https://aws.amazon.com/ecs/)

### What you get when introducing this service to your configuration

* A managed container service running the container `image` specified with the `cpu` and `memory` restrictions you've applied. The service will run on the `port` specified in the configuration
* A DNS record to the value set as your `domain` in the configuration
* A load balancer routing HTTP and HTTPS traffic to the container
* An SSL certificate for the domain name(s) specified

### Required attributes

* `type` - **string** - It should be set to `application`
* `image` - **string** - The docker image to run, for example `stackmate/sample-nodejs-app:latest`. It should be anything that Docker can pull from (for example a public DockerHub repository)
* `port` - **number / Optional for non-web services** - The port that your web application runs on. If your application doesn't expose a port (for example it's a backend worker or something similar), feel free to leave this empty

### Optional attributes

* `cpu` - **number** - The vCPU units that your container runs on. Acceptable values are: `0.25`, `0.5`, `1`, `2`, `4`, `8` and `16`.
* `memory` - **number** - The GB of memory available that the container runs on. You can use `0.5` and any integer value between `1` and `120` but please keep in mind that cloud providers might introduce some restrictions:
  * Available AWS [CPU and Memory combinations](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-tasks-services.html#fargate-tasks-size)
* `domain` - **string** - The domain name to use for your service. It can be both top-level domains (eg. stackmate.io) or subdomains (eg. app.stackmate.io)
* `www` - **boolean** - Whether to add another DNS record that starts with`www` (eg. [www.stackmate.io](http://www.stackmate.io)). Please note: This only applies when using a top-level domain name as `domain` (like eg. stackmate.io)

### Example configuration for an application container on AWS ECS

{% code title=".stackmate/config.yml" %}

```yaml
---
state:
  bucket: ...
  lockTable: ...

environments:
  production:
    nodejs-app:
      type: application
      image: stackmate/sample-nodejs-app:latest
      cpu: 0.5
      memory: 1
      port: 3000
      domain: stackmate.io
      # provider: aws # implied, since aws is the default provider
```

{% endcode %}

The example above will run a container of `0.5` vCPU, `1` GB of memory, that will expose port `3000` on AWS ECS Fargate. It will also create an application load balancer that will forward traffic to the container, using an auto-generated SSL certificate via ACM for `stackmate.io`. Finally, there will be a DNS record on Route53 with `stackmate.io` as the domain name, targeting the load balancer.


# Database services

Stackmate offers infrastructure deployment for major managed database services (like AWS RDS for example)

### What you get when introducing this service to your configuration

* A managed database instance with sane defaults

### Required attributes

* `type` - **string** - It should be either `mysql`, `postgresql` or `mariadb`

### Optional attributes

* `provider` - **string** - by default is set to `aws`
* `size` - **string** - The instance size. Should be one of the instances the cloud provider has available
* `version` - **string** - The database version to use. These are dictated by the cloud provider (eg. AWS) and it's one of the versions they currently support.
* `storage` - **number** - The size of the storage space in Gigabytes
* `database` - **string** - The name of the database to deploy
* `port` - **number** - The port to use. By default, `3306` is assigned to `mysql` and `mariadb` and `5432` for `postgresql`
* `monitoring` - **object** - Any monitoring options available for the service. Example configuration is shown below

The typical [Common Service Options](/configuration/configuration-file/environments#common-service-options) apply here too.

### Credentials for the root user:

The password for the root user associated with the database, is stored as a secret on your provider, you can link directly to it through your provider's secret manager (eg. AWS secrets manager)

### Example configuration

```yaml
# ... the rest of the configuration ...
environments:
  production:
    # ... more services ...
    my-database:
      type: mysql
      provider: aws         # optional when your provider's set to aws
      region: eu-central-1  # optional if you have a region set for the project
      size: db.t2.micro
      storage: 30
      version: 8.0
      database: my-database
      profile: default      # this is the default
      monitoring:
        urls:
          - https://a-webhook-to-get-alerted-by.com
        emails:
          - database-alerts@mywebsite.com
```


# Cache Services

Stackmate offers infrastructure deployment for major managed cache services (like AWS Elasticache for example)

### What you get when introducing this service to your configuration

* A managed cache instance with sane defaults

### Required attributes

* `type` - **string** - It should be either `redis` or `memcached`

### Optional attributes

* `size` - **string** - The instance size. Should be one of the instances the provider has available
* `version` - **string** - The cache version to use. These are dictated by the cloud provider (eg. AWS) and it's one of the versions they currently support.
* `storage` - **number** - The size of the storage space in Gigabytes
* `port` - **number** - The port to use. By default, `6379` is assigned to `redis` and `11211` is assigned to `memcached`
* `monitoring` - **object** - Any monitoring options available for the service. Example configuration is shown below

The typical [Common Service Options](/configuration/configuration-file/environments#common-service-options) apply here too.

### Example configuration

```yaml
# ... the rest of the configuration ...
environments:
  production:
    # ... more services ...
    my-cache:
      type: redis
      provider: aws         # optional when your provider's set to aws
      region: eu-central-1  # optional if you have a region set for the project
      size: cache.t3.micro
      storage: 30
      version: 7.0
      monitoring:
        urls:
          - https://a-webhook-to-get-alerted-by.com
        emails:
          - cache-alerts@mywebsite.com
```


# Object storage

Stackmate offers infrastructure deployment for object storage services (like AWS S3 for example)

### What you get when introducing this service to your configuration

* As many object storage buckets you've specified in your configuration with versioning, encryption or public access configured

### Required attributes

* `type` - **string** - It should be set to `objectstore`
* `buckets` - **array** - a list of objects with the following attributes:
  * `name` - **string, required** - the bucket's name
  * `versioning` - **boolean, optional** - whether to enable versioning for objects, `false` by default
  * `encrypted` - **boolean, optional** - whether objects are encrypted in the bucket, `false` by default
  * `publicRead` - **boolean, optional** - whether the objects are publicly available for reading, `false` by default

The typical [Common Service Options](/configuration/configuration-file/environments#common-service-options) apply here too.

### Accessing the bucket

{% hint style="info" %}
Please read the following if you plan to grant programmatic access to your buckets
{% endhint %}

Stackmate creates a user in your cloud that is able to access and manage objects in the newly created bucket and a policy is assigned to it. The user does not have any credentials assigned to it, so you should log in through your console and create them yourself.

### Example configuration

```yaml
# ... the rest of the configuration ...
environments:
  production:
    # ... more services ...
    my-storage:
      type: objectstore
      buckets:
        - name: my-super-bucket
          versioning: true
        - name: my-other-awesome-bucket
          encrypted: true
```


# stackmate preview

The `stackmate preview` command shows the changes that will be applied to the stack after you've updated your configuration file

### Usage

```
stackmate preview <environment> [-c configuration.yml -d working-directory]
```

### Arguments

* `<environment>` The environment to preview the changes for

### Options

* `--configuration <file>, -c <file>` the configuration file to be used for this operation. By default `.stackmate/config.yml` is used
* `--directory <dir>, -d <dir>` the directory to use as a working one, where the [Output files](/guides/output-files) will be generated&#x20;


# stackmate deploy

{% hint style="info" %}
If you're looking to deploy every time you push a new commit, perhaps you might want to check our [Cloud](https://stackmate.io/cloud/) version out. We offer a **trial of 7 days** and **no credit card** is required.
{% endhint %}

The `stackmate deploy` command applies changes to an environment specified. It is responsible for deploying and modifying your infrastructure.

### Usage

```
stackmate deploy <environment> [-c configuration.yml -d working-directory]
```

### Arguments

* `<environment>` The environment to deploy

### Options

* `--configuration <file>, -c <file>` the configuration file to be used for this operation. By default `.stackmate/config.yml` is used
* `--directory <dir>, -d <dir>` the directory to use as a working one, where the [Output files](/guides/output-files) will be generated&#x20;


# stackmate destroy

{% hint style="danger" %}
**WARNING!** This will tear down your entire infrastructure **without any confirmation**, use when you're completely sure about what you're doing!
{% endhint %}

The `stackmate destroy` command applies **completely destroys your entire infrastructure**.

### Usage

```
stackmate destroy <environment> [-c configuration.yml -d working-directory]
```

### Arguments

* `<environment>` The environment to destroy

### Options

* `--configuration <file>, -c <file>` the configuration file to be used for this operation. By default `.stackmate/config.yml` is used
* `--directory <dir>, -d <dir>` the directory to use as a working one, where the [Output files](/guides/output-files) will be generated&#x20;


# Use your own VPC on AWS

Stackmate deploys a VPC for every environment it handles. For example, if you have two environments, `production` and `staging`, you'll get two different VPCs when finished deploying.

By default, AWS has a limit of 5 VPCs per account, which means that you should either be re-using a VPC you've already used elsewhere, or reach out to the AWS support to have them increase your VPC quota.

In our example, we'll create and use a VPC that we'll add to our stackmate configuration.

* First, let's create a VPC on AWS: We can create the VPC using the Console by following [this document](https://docs.aws.amazon.com/vpc/latest/userguide/create-vpc.html#create-vpc-only), or use the AWS CLI by following [this one](https://docs.aws.amazon.com/vpc/latest/userguide/create-vpc.html#create-vpc-cli) instead.&#x20;
* Next, we need to grab the VPC ID and the Root IP used to create the CIDR blocks on the VPC
* In our example, we assume that the VPC ID is `vpc-1234567` and the CIDR block will be `19.0.0.0/24` which means that our root IP address is `19.0.0.0`
* We need to add a `provider` service on our configuration as follows:

{% code title=".stackmate/config.yml" %}

```yaml
---
state:
  bucket: ...
  lockTable: ...
environments:
  production:
    aws:
      type: provider
      vpcId: "vpc-1234567"
      rootIp: "19.0.0.0"
    app:
      type: application
      # ... the rest of the configuration here ...
```

{% endcode %}

What stackmate will do next then, is to import the vpc specified, and use this as the reference VPC for your AWS services


# Handle SSL failures for AWS

As described on the [Application service](/configuration/application-services#what-you-get-when-introducing-this-service-to-your-configuration) configuration section, stackmate will add an SSL certificate for your environment, that will handle the domain names you specified in your project.&#x20;

### Using email validation

Stackmate will instruct AWS to try and validate the certificate using `email` by default, where you will get prompted to approve the validation request or not. What you need to know beforehand is the following:

* AWS will email the `administrator`, `hostmaster`, `postmaster`, `webmaster` and `admin`  inboxes at your domain so it's necessary to have at least one of these inboxes available, or a catch-all inbox at hand.
* The approval should be done within 5 minutes after you get the email, otherwise the deployment will fail
* There have to be a few CAA DNS records in your domain name so that AWS can issue the certificate for you as described in [this document](https://docs.aws.amazon.com/acm/latest/userguide/setup-caa.html). Our experience shows that just setting a CAA record for `amazon.com` will work, but we can't guarantee that.

### Using DNS validation

Alternatively, you can also use DNS validation for your SSL certificates but the domain needs to be active and the name servers for it need to already be pointing to AWS. What you need to do is the following:

* Create a Hosted Zone for your domain name (eg. stackmate.io) on Route53 as described in [this document](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/CreatingHostedZone.html).
* Get the NS records and set them as your nameservers on your domain registrar.

Stackmate will then attempt to validate whether the DNS records are active and use that as the validation method so that no manual action will be required


# License

Stackmate is released under the MIT license

#### References

{% embed url="<https://opensource.org/licenses/MIT>" fullWidth="false" %}


