1.0.0-beta.3 • Published 1 month ago

cloudsite v1.0.0-beta.3

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
1 month ago

Cloudsite

Low cost, high performance cloud based website hosting manager. Cloudsite features CDN integration, DoS protection, free SSL certificates, and contact forms. In addition, since Cloudsite use "pay as you go" cloud infrastructure, hosting costs are generally well below typical market rates.

If you appreciate this project, you can support us on Patreon @zanecodes. We also provide support on our discord channel.

Installation

CLI installation

npm i -g cloudsite

Library installation

npm i --omit peer cloudsite

All the peer dependencies are specific to the CLI, so if you're not using the CLI, you can omit them.

Usage

CLI usage

# authenticate with AWS; see below for options
aws sso login --profile your-sso-profile 

cloudsite configuration initialize # walks you through setup questions
# deploys a robust, high performance static site in the cloud
cloudsite create your-domain.com --source-path . # see 'Plugins' for additional options
cloudsite update your-domain.com # updates site content
cloudsite destroy your-domain.com # destroys site infrastructure

See Command reference for all the CLI commands.

Library usage

import { create } from 'cloudsite'

const siteInfo = {
  "apexDomain": "your-website-domain.com",
  "sourceType": "docusaurus", // or 'vanilla'
  "sourcePath": "/Users/your-home-dir/path/to/website/source"
  "plugins": {
    "contactHandler": {
      "settings": {
        "path": "/contact-handler",
        "emailFrom": "contactform@your-website-domain.com"
      }
    }
  }
}

create({ siteInfo }) // siteInfo gets updated with additional info as the site is created

console.log('Final site info:\n' + JSON.stringify(siteInfo))
// you'll probably want to save 'siteInfo' somewhere for future operations on the same site

AWS authentication

Cloudsite works by setting up AWS infrastructure within your own AWS account. There are two basic methods to authenticate: access keys and SSO login. Of the two, SSO login is recommended by AWS and is generally the safer alternative; access keys are a less secure method in that the access keys persist on your hard drive so if your computer is compromised, your AWS account would be vulnerable. Access keys, however, are a little easier/quicker to set up.

If you aren't in a hurry, you might want to set up SSO authentication to start with. Otherwise, you can setup access key authentication to get started quickly and then set up SSO authentication later (and then delete + disable your access keys).

Sign up for your AWS account

If you don't already have one, the first step is to create your AWS root account.

  1. If you are working on behalf of an organization and have the ability to create email aliases, we suggest you first create 'awsroot@your-domain.com' and use that to sign up.
  2. Navigate to aws.amazon.com.
  3. Click 'Create an AWS Account' or 'Create a Free Account'.
  4. Fill out the required information.

SSO authentication

SSO authentication uses the new AWS Identity Center to enable single-sign on across multiple AWS accounts. SSO is also integrated with the aws CLI tool and is the method by which we can create time-limited session credentials.

Set up the CloudSiteManager policy

  1. Log into your AWS root account in the AWS console.
  2. In the 'Services' bar up top, search for 'IAM' and select that service or click here.
  3. Select 'Policies' from the left hand menu options.
  4. Select 'Create policy'.
  5. Select the 'JSON' option.
  6. From the command line, execute:
    cloudsite get-iam-policy
  7. Copy the output from the terminal and replace the JSON text in the Policy editor with the text from the terminal.
  8. Click 'Next'.
  9. Under 'Policy name' enter 'CloudSiteManager' and click 'Create policy'.

Create SSO user, group, and set permissions

First, we need to create your SSO user. It's considered best practice to assign permissions to groups and then add users those groups, so that's what we're going to do.

  1. Log into your AWS root account in the AWS console.
  2. In the 'Services' bar up top, search for 'IAM Identity Center' and select that service or click here.
  3. From the left-hand menu of AWS Identity Center, select 'Users'.
  4. Select 'Add user'.
  5. Fill out the 'Primary information'. This is your account, so choose your own username and use your personal email address. You're welcome to fill out additional fields if you like. When finished, click 'Next'.
  6. We'll create the group in a second, so just click 'Next' on the 'Add users to groups' page.
  7. Review the information and click 'Add user'.
  8. From the left-hand menu, select 'Groups'.
  9. Select 'Create group'.
  10. For group name, enter 'cloudsite-managers' (or whatever you prefer). In the 'Add users to group' section, click the checkmark by the user you just created.
  11. From the left-hand menu, select 'Permission sets'.
  12. Under 'Types', select 'Custom permission set' and then hit 'Next'.
  13. Expand the 'Customer Managed Policies' section and click 'Attach policies'.
  14. Where it says 'Enter policy names', enter 'CloudSiteManager' and hit next.
  15. On the 'Specify permission set details' page, under 'Permission set name', enter 'CloudSiteManager'. When done, hit 'Next'.
  16. Review and click 'Create'.
  17. From the left-hand menu, select 'AWS accounts'.
  18. You should see your root account listed. Click the checkbox next to the root account and click 'Assign users or groups'.
  19. Select the 'Cloudsite managers' group you just created (or whatever you called it).
  20. On the 'Assign permission sets' page, select 'PowerUserAccess' and click 'Next'.
  21. Review and click 'Submit'.
  22. Just to make things a little nicer, let's rename your SSO access portal page. On the right hand side, in the 'Settings summary' box, click 'Edit' next to 'Instance name'.
  23. Choose a (free) instance name; this could be based on your own name or your organization's. We used 'liquid-labs'.
  24. You should receive an email titled something like 'Invitation to join AWS IAM Identity Center'. Open that email and click the 'Accept invitation'. This will take you to AWS Identity Center and ask you to create a password for the account.

Local SSO configuration and authentication

  1. Follow the instructions to Install or update to the latest version of the AWS CLI.
  2. You can follow Configure the AWS CLI to use IAM Identity Center token provider credentials with automatic authentication refresh, which is summarized in the following steps.
  3. Have your IAM Identity Center page open.^1
  4. Run the command aws configure sso
    1. Choose a 'session name', we called ours 'liquid-labs-sso'.
    2. For the 'SSO Start URL', copy your 'AWS access portal URL' from IAM Identity Center 'Settings summary' on the right hand side of the dashboard page.
    3. For the 'SSO region', copy the value from 'Region' ID from the 'Settings summary' section. It'll be something like 'us-east-1'.
    4. For 'SSO registration scopes', accept the default 'sso:account:access'.
    5. At this point, a browser window should open and ask you to log in as the SSO user we created earlier. Log in and start your SSO session.
    6. You should get a message that you will be using the 'PowerUserAccess' role we created earlier.
    7. Next, you should be asked for the 'CLI default client Region'. We recommend 'us-east-1' (regardless of the region where your IAM Identity Center instance resides).^2
    8. For the 'CLI default output format', you can accept the default of 'None'.
    9. For the 'CLI profile name', enter something memorable. We used 'll-power-user'.
  5. Now you're all set. From now on, just execute the following to create temporary session credentials cloudsite can use:
    aws sso login --profile your-profile-name
    Replace 'your-profile-name' with the name of the profile created in the previous step.

You're now ready to use the cloudsite CLI tool. In future, you need only execute the aws sso login --profile your-profile-name command prior to using the cloudsite command or if your session times out.

^1: If you created your IAM Identity Center instance in a different region (than 'us-east-1'), you'll have to select the proper region. AWS provides an explanation and a link to your instance if you're in the wrong region.

^2: This is just because the Certificate Manager service—which issues your site's SSL certificates—only operations out of the 'us-east-1' region. It should be possible to create your site in any region, but having all the infrastructure in one region is helpful and with the use of CDN, it shouldn't matter too much which region the rest of the infrastructure resides.

Authenticating with access keys

As an alternate method to setting up SSO, you can also set up access keys. You don't need to both unless you're setting up SSO authentication to replace access keys authentication.

As mentioned, access keys are considered a bit less safe since anyone that gets ahold of your access keys would have access to your AWS account. For most individuals, access keys are reasonable alternative.

We're going to start by following best practices and creating a group. We'll then add permissions to that group. Next, we create a non-root user and add them to the group we just created. Finally, we'll create access keys which we can use for local authentication.

  1. First, navigate to the AWS console (and log in if necessary).
  2. In the 'Services' search in the upper left-hand side, search for 'IAM' and click the service. (Here, you want plain 'IAM', NOT 'IAM Identity Center'.)
  3. From the left-hand side, select 'User groups' and click 'Create group'.
  4. For the group name, we recommend something like 'website-managers', but feel free to name it whatever you like.
  5. In the 'Attach permission policies' section, search for 'PowerUserAccess'. Find the 'PowerUserAccess' policy in the list and click the checkbox next to it.
  6. Click 'Create group'.
  7. From the left-hand side, select 'Users'. Enter the 'User name'; this could be your own username or something like 'website-manager'.
  8. On the 'Set permissions' page, in the 'User groups' section, click the checkbox next to the group we just created. Then click 'Next'.
  9. Review and click 'Create user'.
  10. Select the 'Users' option from the left-hand menu. (It's probably already selected.)
  11. Click on the user we just created.
  12. In the details section (below 'Summary'), click the 'Security credentials' tab.
  13. Scroll down to 'Access keys' and click 'Create access key'.
  14. For 'Use case', select 'Local code'. Click the "I understand" checkbox below and hit 'Next'.
  15. Click 'Create access key'. Keep the next page, 'Retrieve access keys' open!
  16. Create (or modify) the file ~/.aws/credentials with the following text:
    [default]
    aws_access_key_id = ABCDEFGHIJKLMOP
    aws_secret_access_key = abcdefghijk123456789
    Copy the 'Access key' from the 'Retrieve access keys' page and replace the value for 'aws_access_key_id'. Do the same with 'Secrete access key' from the 'Retrieve access keys' page and replace the value for 'aws_secrete_access_key'.

The cloudsite tool will now use your the above configured access key by default.

Plugins

Cloudsite uses a simple plugin system and at the moment, it's more like "optional features" than full plugins, but it'll get there. There are currently two plugins supported: contact form and CloudFront logging.

Contact form

Supports a single contact with set fields. User defined fields will be supported in a future version.. Currently, the supported fields are:

  • given_name,
  • family_name,
  • email,
  • topics, and
  • message.

When submitted, the form data will be saved in a DynamoDB table and the information will be optionally mailed to a user defined email address. The form processing routine supports both base64 form encoded data and a JSON body.

Configuration options

  • contactHandler.emailFrom (string): The SES verified email to use when sending a submission notification email.
  • contactHandler.emailTo (string): The optional target email. If not provided, emailFrom will be used for both the sender and target.
  • contactHandler.path (string): The absolute URL path (beginning with /) where the form submission handler is called. Use this path in the form action, or JS fetch call and the POST method.

Usage

  1. Set up the form on your website. Set the submit handler to whatever you like (we use '/contact-handler'). We will provide at least one template site for this soon. Until then, if you want immediate support, hit us up on discord.
  2. Activate AWS Simple Email Service (SES).
    • Sign in to the AWS Management Console and open the Amazon SES console at https://console.aws.amazon.com/ses/.
    • Make sure you're setting up SES in the same region as your site. This will be us-east-1 unless you specified a different --region option when you create/created the site.
    • Select 'Get started' (or 'Get set up' maybe) from the SES console home page and the wizard will walk you through the steps of setting up your SES account.
  3. It is recommended that you not use your personal email directly and instead create an alias your account. Then use the alias as the destination account.
  4. To create a site infrastructure with contact form support, you must at a minimum define contactHandler.emailFrom and contacteHandler.path. This can be done during site creation like so (can be combined with other options):
    cloudsite create your-domain.com --source-path . \
      --option contactHandler.path:/contact-handler \
      --option contactHandler.emailFrom:contactform@your-domain.com
  5. Include the optional contactHandler.emailTo setting if you want to send the email to a different address than the "from" email.

See also Updating your site.

CloudFront logging

Enables logging of CloudFront events to an S3 bucket. The infrastructure will create a common logging bucket to receive the logs. Currently, the bucket name is hard coded and will be something like 'your-domain-com-common-logs'.

Configuration options

  • cloudfrontLogs.includeCookies (boolean): Indicates whether to include cookie data in the logs.

Usage

To create infrastructure that includes CloudFront event logs, use the following command (can be combined with other options):

cloudsite create your-domain.com --source-path . \
  --option cloudfrontLogs.includeCookies:true # or false

Setting the option, to either 'true' or 'false' is what enables the CloudFront logs.

See also Updating your site

Updating your site

You can update your site, to add, remove, or reconfigure plugins/options with the 'pluggin-settings' command. For instance, to activate contact form support, you could execute:

cloudite plugin-settings your-domain.com \
  --option contactHandler.path:/contact-handler \
  --option contactHandler.emailFrom:contactform@your-domain.com

and then run:

cloudsite update your-domain.com

Command reference

Usage

cloudsite <options> <command>

Main options

OptionDescription
<command>(main argument,optional) The command to run or a sub-command group.
--formatSets the format for the output. May be 'terminal' (default), 'text', 'json', or 'yaml'.
--help, -?Prints general or command specific help.
--no-colorDisables terminal colorization.
--no-reminders, -RSuppresses any reminders. Particularly useful for programmatic usage where the extra output might break things.
--quiet, -qMakes informational output less chatty.
--sso-profileThe AWS local SSO profile to use for authentication.
--throw-errorIn the case of an exception, the default is to print the message. When --throw-error is set, the exception is left uncaught.
--verboseActivates verbose (non-quiet mode) even in situations where quiet would normally be implied.

Commands

  • cleanup: Attempts to fully delete partially deleted sites in the 'needs to be cleaned up' state.
  • configuration: Command group for managing the Cloudsite CLI configuration.
  • create: Creates a new website, setting up infrastructure and copying content.
  • destroy: Destroys the named site. I.e., deletes all cloud resources associated with the site.
  • detail: Prints details for the indicated site.
  • get-iam-policy: Prints an IAM policy suitable for operating cloudsite.
  • import: Generates a site database based on currently deployed site stacks.
  • list: Lists the sites registered in the local database.
  • plugin-settings: Sets (or deletes) a site option.
  • update: Updates a website content and/or infrastructure.
  • verify: Verifies the site is up and running and that the stack and content are up-to-date.

cloudsite cleanup <options> <apex-domain>

Attempts to fully delete partially deleted sites in the 'needs to be cleaned up' state.

cleanup options
OptionDescription
<apex-domain>(main argument,optional) Specifies the site to clean up rather than trying to cleanup all pending sites.
--listLists the sites in need of cleaning up.

cloudsite configuration [subcommand]

Command group for managing the Cloudsite CLI configuration.

configuration options
OptionDescription
[subcommand](main argument,required) The configuration action to perform.
Subcommands
  • initialize: Runs the initialization wizard and updates all options.
  • show: Displays the current configuration.

cloudsite configuration initialize

Runs the initialization wizard and updates all options.

cloudsite configuration show

Displays the current configuration.

cloudsite create <options> <apex-domain>

Creates a new website, setting up infrastructure and copying content.

create options
OptionDescription
<apex-domain>(main argument,optional) The site apex domain.
--bucket-nameThe name of the bucket to be used. If no option is given, cloudsite will generate a bucket name based on the apex domain.
--no-buildSupresses the default behavior of building before uploading the site content.
--no-delete-on-failureWhen true, does not delete the site stack after setup failure.
--no-interactiveSuppresses activation of the interactive setup where it would otherwise be activated.
--optionA combined name-value pair: :. Can be used multiple times. With '--delete', the value portion is ignored and can be omitted, e.g.: '--option '.
--regionThe region where to create the site resources. Defaults to 'us-east-1'.
--source-pathLocal path to the static site root.
--source-typeMay be either 'vanilla' or 'docusaurus', otherwise process will attempt to guess.
--stack-nameSpecify the name of the stack to be created and override the default name.

cloudsite destroy <options> [apex-domain]

Destroys the named site. I.e., deletes all cloud resources associated with the site.

destroy options
OptionDescription
[apex-domain](main argument,required) The domain of the site to delete.
--confirmedSkips the interactive confirmation and destroys the resources without further confirmation.

cloudsite detail [apex-domain]

Prints details for the indicated site.

detail options
OptionDescription
[apex-domain](main argument,required) The domain of the site to detail.

cloudsite get-iam-policy <options>

Prints an IAM policy suitable for operating cloudsite.

get-iam-policy options
OptionDescription
--with-instructionsWhen set, will print instructions for creating the policy along with the policy.

cloudsite import <options> [domain-and-stack]

Generates a site database based on currently deployed site stacks.

import options
OptionDescription
[domain-and-stack](main argument,required) The domain and stack are specified as positional parameters, in either order.
--common-logs-bucketSpecifies the common logs bucket name. This is only necessary if there are multiple candidates, otherwise cloudsite can usually guess. Set to 'NONE' to suppress guessing and assume there is on common logs bucket.
--refreshBy defaualt, cloudsite will refuse to overwrite existing site DB entries. if '--refresh' is true, then it will update/refresh the existing entry.
--regionSpecifies the region where the stack is to be found.
--source-pathLocal path to the static site root.
--source-typeMay be either 'vanilla' or 'docusaurus', otherwise process will attempt to guess.

cloudsite list <options>

Lists the sites registered in the local database.

list options
OptionDescription
--all-fieldsIncludes all fields in the output.

cloudsite plugin-settings [subcommand]

Sets (or deletes) a site option.

plugin-settings options
OptionDescription
[subcommand](main argument,required) The subcommand to execute.
Subcommands
  • set: Sets and deletes the specified options.
  • show: Displays the plugin settings for the specified site.

cloudsite plugin-settings set <options> [apex-domain]

Sets and deletes the specified options.

set options

OptionDescription
[apex-domain](main argument,required) The apex domain of the site to configure.
--confirmedWhen entirely deleting (disabling) a plugin, you must either confirm interactively or provide the '--confirmed' option.
--deleteWhen set, then deletes the setting. Incompatible with the '--value' option. To delete all plugin settings (disable the plugin), set '--name' or '--option' to the bare plugin name; e.g.: --value aPlugin.
--nameThe option name.
--optionA combined name-value pair: :. Can be used multiple times. With '--delete', the value portion is ignored and can be omitted, e.g.: '--option '.
--valueThe setting value. Incompatible with the '--delete' option.

cloudsite plugin-settings show [apex-domain]

Displays the plugin settings for the specified site.

show options

OptionDescription
[apex-domain](main argument,required) The apex domain of the site whose settings are to be displayed.

cloudsite update <options> [apex-domain]

Updates a website content and/or infrastructure.

update options
OptionDescription
[apex-domain](main argument,required) The apex domain identifying the site.
--do-billingLimits updates to billing related matters (cost allocation tags) and other other specified updates.
--do-contentLimits update to site content and any other specified updates.
--do-dnsLimits update to DNS entries and any other specified updates.
--do-stackLimits update to stack infrastructure and any other specified updates.
--no-buildSupresses the default behavior of building before updating the site.
--no-cache-invalidationSuppresses the default behavior of invalidating the CloudFront cache after the files are updated. Note that invalidation events are chargeable thought at the time of this writing, each account gets 1,000 free requests per year.

cloudsite verify <options> [apex-domain]

Verifies the site is up and running and that the stack and content are up-to-date.

verify options
OptionDescription
[apex-domain](main argument,required) The domain of the site to verify.
--check-contentIf set, then checks content and skips other checks unless also specifically specified.
--check-site-upIf set, then checks that the site is up and skips other checks unless also specifically specified.
--check-stackIf set, then checks for stack drift and skips other checks unless also specifically specified.

Documentation generated.

Known limitations

  • The permissions used by the 'ContactHandler' Lambda function are overly broad and need to be narrowed. See issue #34.

Contributing

Plase feel free to submit any bug reports or feature suggestions. You're also welcome to submit patches of course. We don't have a full contributors policy yet, but you can post questions on our discord channel. It's not monitored 24/7, but you should hear back from us by next business day generally.

Support and feature requests

The best way to get free support is to submit a ticket. You can also become a patron for as little as $1/month and get priority support and request new feature on all Liquid Labs open source software. You can get these benefits and support our work at patreon.com/zanecodes.