Manage your infrastructure in one place
By default, Shelter is looking for a directory named resources
with a
subdirectory name templates
.
In the templates subdirectory, we can define different templates. They
have to be a valid CloudFormation .yaml
file.
In the resources directory, we can define different resources. They have
to be defined in .yaml
format with a few specific tags in it.
+-- resources
| +-- templates
| | `-- restricted-s3.yaml
| `-- testbucketresource.yaml
You can specify where is your resources directory in Shelterfile.rb
with resource_directory
.
In our example above, we have only one template named restricted-s3
.
This template defined a CloudFormation stack that contains an S3 bucket,
an IAM User and a Policy for that specific user which restricts the user
to be able to reach only our new S3 Bucket, but nothing else. For the
IAM User, we create a new AccessKey pair, so we can use the
credentials in our infrastructure. Now, for the simplicity, we did not
define a KMS key.
As an output we export the newly created AccessKeyID
and
AccessKeySecret
pair.
We have three template parameters:
resources/templates/restricted-s3.yaml
---
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
BucketName:
Type: String
Description: Created S3 bucket
Client:
Type: String
Description: Name of the client for tagging
Project:
Type: String
Description: Project tag
Resources:
Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref BucketName
Tags:
- { Key: "project", Value: !Ref Project }
- { Key: "client", Value: !Ref Client }
S3Policy:
Type: "AWS::IAM::Policy"
Properties:
PolicyName: !Join ["-", ["s3", !Ref BucketName]]
Users:
- !Ref NewUser
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "s3:PutObject"
- "s3:GetObjectAcl"
- "s3:GetObject"
- "s3:GetObjectTorrent"
- "s3:GetBucketTagging"
- "s3:GetObjectTagging"
- "s3:ListBucket"
- "s3:PutObjectTagging"
- "s3:DeleteObject"
Resource:
- !GetAtt [Bucket, Arn]
- !Join ["", [!GetAtt [Bucket, Arn], "/*"]]
NewUser:
Type: "AWS::IAM::User"
Properties:
UserName: !Join ["-", ["s3", !Ref BucketName, "user"]]
Path: /
AccessKey:
Type: AWS::IAM::AccessKey
Properties:
UserName: !Ref NewUser
Outputs:
AccessKeyID:
Value:
!Ref AccessKey
SecretKeyID:
Value: !GetAtt AccessKey.SecretAccessKey
Now we have a template named restricted-s3
. We can start creating
resources with this template. For now, we can create a backup user and S3
bucket, so all of our servers with a specific label can call AWS API to
make some backup on our specific S3 bucket.
Let’s create a file under resources:
resources/testbucketresource.yaml:
---
name: testbucketresource
template: restricted-s3
capabilities:
- CAPABILITY_NAMED_IAM
tags:
random: yes
project: test
client: cheppers
extra: something
parameters:
BucketName: my-testresource
Client: cheppers
Project: test
Here we go. Basically, all of the keys in this file are required, or if we don’t define them, they will be empty (like tags).
Name: This will be the name of our resource. It will be stack
name as well but prefixed with the res-
string. In this case
res-testbucketresource
.
Template: This value defines which one of our template we want to
use. In this case, we want to use our only one restricted-s3
which is
defined in resources/templates/restricted-s3.yaml
.
Capabilities: AWS CloudFormation capabilities. For more details check the
AWS API Documentation.
Now we want to manage IAM resources, so we need CAPABILITY_IAM
in general, but now we give them custom names so we need
CAPABILITY_NAMED_IAM
.
Tags: This is a simple key-value list. Our CloudFormation stack will be tagged with these tags.
Parameters: This is a simple key-value list. That’s how we can define parameters for our CloudFormation template.
Commands:
shelter resource create <resource-name> # Create a specific resource
shelter resource delete <resource-name> # Delete a specific resource
shelter resource help [COMMAND] # Describe subcommands or one specific subcommand
shelter resource list # List all managed resources
shelter resource output <resource-name> # Display resource output
shelter resource status <resource-name> # Resource status
shelter resource update <resource-name> # Update a specific resource
With list
we can check our resource inventory.
$ bundle exec shelter resource list
testbucketresource
With create
, we can create a specific resource.
$ bundle exec shelter resource create testbucketresource
Waiting for 'stack_create_complete' on 'res-testbucketresource'...
With update
, we can update a specific resource.
$ bundle exec shelter resource update testbucketresource
Waiting for 'stack_update_complete' on 'res-testbucketresource'...
With status
, we can ask for the stack status.
$ bundle exec shelter resource status testbucketresource
Resource ID: AKIXXXXXXXXXXXXXXXXX
Resource Type: AWS::IAM::AccessKey
Resource Status: CREATE_COMPLETE
Resource ID: cheppers-testresource
Resource Type: AWS::S3::Bucket
Resource Status: CREATE_COMPLETE
Resource ID: s3-cheppers-testresource-user
Resource Type: AWS::IAM::User
Resource Status: CREATE_COMPLETE
Resource ID: res-t-S3Po-W66XXXXXXXXX
Resource Type: AWS::IAM::Policy
Resource Status: CREATE_COMPLETE
If we defined Outputs in our template, we can easily list them all with
the output
command.
$ bundle exec shelter resource output testbucketresource
AccessKeyID: AKIXXXXXXXXXXXXXXXXX
SecretKeyID: 3cXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXuI
With delete
we can delete the whole stack.
$ bundle exec shelter resource delete testbucketresource
Waiting for 'stack_delete_complete' on 'res-testbucketresource'...