Skip to content

Resources operations

snripa edited this page Aug 4, 2020 · 5 revisions

General info

We use one S3 bucket to store state.

S3 bucket name: exberry-terraform-states (see issue to make it parametrized)

S3 bucket content has strict structure and is coupled to the notion of "account".

Account is part of JWT token claims ([..., "account:develop", "account:staging", ... ] for example.

User having claims for specific account can manipulate resources that "belong" to this account, and "on behalf" of this account.

"On behalf" - means using aws AMI and role, that are set in "accounts" vault path. (will talk later) "belong" - means created using the account owner's credentials (in case of aws - aws_access_key and aws_secret_key

Accounts

Account stands for the entity that owns the resources. That means, it has aws (or another provider's) credentials used to create resources. Also, that means that account owner can update/delete resources that already exist under that account.

Accounts data are stored under Vault path:

$base_path/accounts/$account_name

For now, one account has these attributes:

{
  "aws_access_key": "xyz",
  "aws_secret_key": "abc",
  "role_arn": "arn:aws:iam::IAM_ID:role/role_name"
}

IAM are the same, but roles are different depending on account name. Roles need to be set up in AWS account having the following permissions (access to S3 bucket and dynamodb table for terraform backend):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::$bucket_name"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::exberry-terraform-states/$account/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:DeleteItem"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/$terraform-lock-table"
        }
    ]
}
  • $terraform-lock-table - name of dynamodb table used to lock terraform states (used in TF backend configuration ( has to be configurable )
  • $account - account name
  • $bucket_name - name of bucket where all the terraform states are kept

S3 bucket structure

As we see, the permissions that are set to account's arn_role are fine grained. Each account has access to it's own folder in state's bucket. The structure of bucket is the following:

resource state path:

$account_name / $resource_type / $resource_name /

resource files (under the folder that identifies the resource):

terraform.tfstate
resource.tfvars
resource_info.yaml
  • terraform.tfstate - terraform resource's state
  • resource.tfvars - terraform resource's variables (used to create/update resource)
  • resource_info.yaml - resource's meta info: can store variable additional information about the resource (for now - module url and version of tf code)

Resource types

The only resource type supported now is: "cluster"

Access control

In order to manipulate the resource (create/update/delete), the user needs to have a proper claim: "account$account". After, Spinless reads account's secrete from Valut (from well-known path) and attempts to initialize the backend. If the arn_role that is specified in account doesn't provide access to the $bucket/$account folder, the entire request fails.

Besides the "account:$account" claim, user has to have access to resource manipulation endpoint. In general cases, that's "admin:clusters" clam . That's the subject of further changes.

Clone this wiki locally