AWS
Dependencies
baseca
Database Migration
Build and Upload baseca
:
Deploy Compute for baseca
:
Please read the GETTING_STARTED.md
documentation and set up a local development environment before proceeding and deploying the production infrastructure.
brew install tfenv
tfenv install 1.4.2
tfenv use 1.4.2
baseca
Infrastructure Documentation
NOTE: Private CA(s) in acm_pca_arns
must already exist within your infrastructure; refer to the Public Key Infrastructure section if you need to design and deploy a Public Key Infrastructure.
# baseca/terraform/production/baseca.tf
module "baseca" {
source = "./baseca"
service = "baseca"
environment = "production"
region = "us-east-1"
key_spec = "RSA_4096"
bucket = "baseca-firehose-example"
db_ingress = ["10.0.0.0/8"]
acm_pca_arns = [
"arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"arn:aws:acm-pca:us-east-1:987654321098:certificate-authority/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
]
}
cd /path/to/baseca/terraform/production
terraform init
terraform apply
These outputs from Terraform will be utilized within the baseca config.primary.production.aws.yml
configuration file.
terraform output
# Example Output
ecr_repository = "012345678901.dkr.ecr.us-east-1.amazonaws.com/baseca"
kinesis_firehose_stream = "baseca-production"
kms_key_id = "xxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
rds_reader_endpoint = "baseca-production-cluster.cluster-ro-xxxxxxxxxxxx.us-east-1.rds.amazonaws.com"
rds_writer_endpoint = "baseca-production-cluster.cluster-xxxxxxxxxxxx.us-east-1.rds.amazonaws.com"
redis_endpoint = "baseca-production.xxxxxx.0001.use1.cache.amazonaws.com"
Update the config/config.primary.production.aws.yml
configuration file using the outputs from Terraform; an example configuration can be seen within CONFIGURATION.md.
# Update config.primary.production.aws.yml
database:
database_endpoint: baseca-production-cluster.cluster-xxxxxxxxxxxx.us-east-1.rds.amazonaws.com # rds_writer_endpoint
database_reader_endpoint: baseca-production-cluster.cluster-ro-xxxxxxxxxxxx.us-east-1.rds.amazonaws.com # rds_reader_endpoint
redis:
cluster_endpoint: baseca-production.xxxxxx.0001.use1.cache.amazonaws.com # redis_endpoint
firehose:
stream: baseca-production
kms:
key_id: xxxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # kms_key_id
Variable | Description | Update |
---|---|---|
grpc_server_address |
gRPC Server Address and Port | No |
ocsp_server |
Custom OCSP Server URL | Optional |
database |
baseca RDS Database | Yes |
redis |
baseca Elasticache Redis Cluster | Yes |
domains |
List of Valid Domains for baseca x.509 Certificates |
Yes |
firehose |
baseca Kinesis Data Firehose | Yes |
kms |
baseca Customer Managed KMS Key | Yes |
acm_pca |
AWS Private Certificate Authorities | Yes |
secrets_manager |
AWS Secrets Manager | Yes |
subordinate_ca_metadata |
baseca Subordinate CA Attributes | Optional |
certificate_authority |
Environment(s) for acm_pca Private CA(s) |
Yes |
# Update config.primary.production.aws.yml
secrets_manager:
secret_id: rds!cluster-bcc40600-5fa7-4877-aa35-529cae165937
golang-migrate Download Instructions
NOTE: The RDS Cluster should be deployed within a private subnet which means the database migration must be done through an EC2 instance which (a) has network connectivity to the database and (b) is allowed by the security group from the database over Port 5432.
# Launch an Ubuntu EC2 Instance
# Documentation: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html
cd /path/to/baseca
# Copy Database Migration Files and RDS Certificate to EC2
scp -i /path/to/your/key.pem -r db/migration ubuntu@[IP_ADDRESS]:/home/ubuntu
scp -i /path/to/your/key.pem internal/attestor/aws_iid/certificate/rds.global.bundle.pem ubuntu@[IP_ADDRESS]:/home/ubuntu
# SSH to EC2
ssh -i /path/to/your/key.pem ubuntu@[IP_ADDRESS]
# Download golang-migrate
curl -L https://github.com/golang-migrate/migrate/releases/download/v4.16.1/migrate.linux-amd64.tar.gz | tar xvz # AMD64 Example
# Execute Database Migration
./migrate -path migration -database "postgresql://[username]:[password]@[rds_writer_endpoint]:5432/baseca?sslmode=verify-full&sslrootcert=/home/ubuntu/rds.global.bundle.pem" -verbose up
Note: If you see the error below you will need to encode the credentials; please do this locally
and not through an online encoder.
error: parse "postgresql://baseca:[PASSWORD]@[RDS_WRITER_ENDPOINT]:5432/baseca?sslmode=disable": net/url: invalid userinfo
# Update db/init/init.sql for Admin User
VALUES (uuid_generate_v4(), '[email protected]', crypt('ADMIN_CREDENTIALS', gen_salt('bf')), 'Example User', '[email protected]', 'ADMIN', now());
# Copy db.init/init.sql to EC2
scp -i /path/to/your/key.pem db/init/init.sql ubuntu@[IP_ADDRESS]:/home/ubuntu
# SSH to EC2
ssh -i /path/to/your/key.pem ubuntu@[IP_ADDRESS]
# Download Postgres Client
sudo apt-get update
sudo apt-get install -y postgresql-client
# Run Database Init to Create Admin User
psql -h [rds_writer_endpoint] -U [username] -d baseca -f /path/to/init.sql
Note: Terminate
the Migration EC2 Instance After Migration Completed
Use this option by using the published image from baseca
without any code changes or updates to your Dockerfile.
Create Dockerfile
and Copy Configurations
to /home/baseca/config
within the Docker Container.
RELEASE: Search for Latest baseca ghcr.io Published Release
and update the VERSION_SHA
container tag with the latest version.
# baseca/Dockerfile-production
FROM ghcr.io/coinbase/baseca:VERSION_SHA
COPY ./config /home/baseca/config
USER baseca
CMD ["/home/baseca/baseca"]
cd /path/to/baseca/Dockerfile-production
docker build -t baseca -f Dockerfile-production .
Push Image to ECR Registry
docker tag baseca <aws-account-id>.dkr.ecr.<region>.amazonaws.com/baseca:latest
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<region>.amazonaws.com
docker push <aws-account-id>.dkr.ecr.<region>.amazonaws.com/baseca:latest
NOTE: This is an image built from examples/Dockerfile
; there are alternative methods to get the config files onto the image, but you must copy your configurations within the /home/baseca/config
path.
Use this option if you have requirements to change the baseca
image through either custom code changes or updates to the Dockerfile.
NOTE: If you intend to run a local build, within the current Dockerfile
we do not copy the config/
directory into the base image. Additionally within .dockerignore
we ignore the config/
directory as well. If you are running the image directly, the OS directory structure for the final image should be the same as the image in the previous option.
cd /path/to/baseca
docker build -t baseca .
Push Image to ECR Registry
docker tag baseca <aws-account-id>.dkr.ecr.<region>.amazonaws.com/baseca:latest
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws-account-id>.dkr.ecr.<region>.amazonaws.com
docker push <aws-account-id>.dkr.ecr.<region>.amazonaws.com/baseca:latest
DISCLAIMER: The compute deployment is a sample of how baseca
can run within an environment; if you decide to run this ECS Service as is, be cautious as it has not been fully tested. baseca
is not intended to run on ephemeral instances; if a design decision is made to run on ephemeral nodes you will need to have a shared volume such as EFS. The recommended
method is to deploy the service directly on an EC2 instance that supports Nitro Enclaves
; this ensures that key material never leaves the host it was generated on and is never accessible by anything outside of the baseca
process.
baseca
Infrastructure Documentation
# baseca/terraform/production/baseca.tf
module "compute" {
source = "./compute"
service = "baseca"
region = "us-east-1"
environment = "production"
configuration = "production"
vpc_id = "vpc-xxxxxxxx"
subnet_ids = ["subnet-0123456789abcdef", "subnet-9876543210fedcba"]
host_port = 9090
network_ingress = ["10.0.0.0/8"]
public_ip = false
baseca_iam_role = module.baseca.baseca_iam_role
ecr_repository = module.baseca.ecr_repository
depends_on = [
module.baseca
]
}
NOTE: environment
and configuration
are values used to concatenate and build the configuration file for baseca
. Within Terraform we auto export these as environment variables within the ECS Task Definition, but if you are using your own deployment you will need to have these environment variables accessible by baseca
. If the values below were exported then baseca
would read the config/config.primary.production.aws.yml
file. Changing configuration
to development
would read the config/config.primary.development.aws.yml
file.
export ENVIRONMENT=production
export CONFIGURATION=production
cd /path/to/baseca/terraform/production
terraform init
terraform apply