Bootstrapping New Deployments

Bootstrapping is required for new Substation deployments. After the deployment is bootstrapped, all pipelines that run within the deployment can use the bootstrapped resources. We recommend using one deployment per AWS account.

Bootstrapping includes deployment of these resources:

  • KMS encryption key used by all resources across all data pipelines in a deployment
  • ECR image repositories for all Substation AWS applications in a deployment
  • AWS AppConfig applications used by all Substation AWS applications in a deployment
data "aws_caller_identity" "caller" {}

# KMS key that is shared by all Substation resources in the deployment
module "kms_substation" {
  source = "../../../build/terraform/aws/kms"
  name   = "alias/substation"
  policy = <<POLICY
{
  "Version": "2012-10-17",
  "Statement": [
    {
    "Effect": "Allow",
    "Action": [
      "kms:Decrypt",
      "kms:GenerateDataKey"
    ],
    "Principal": {
      "Service": "cloudwatch.amazonaws.com"
    },
    "Resource": "*"
    },
    {
    "Effect": "Allow",
    "Action": "kms:*",
    "Principal": {
      "AWS": "arn:aws:iam::${data.aws_caller_identity.caller.account_id}:root"
    },
    "Resource": "*"
    }
  ]
}
POLICY
}

# AppConfig application that is shared by all Substation apps
resource "aws_appconfig_application" "substation" {
  name        = "substation"
  description = "Stores compiled configuration files for Substation"
}

# Use the prod environment for production resources 
resource "aws_appconfig_environment" "prod" {
  name           = "prod"
  description    = "Stores production Substation configuration files"
  application_id = aws_appconfig_application.substation.id
}

# Use the dev environment for development resources
resource "aws_appconfig_environment" "dev" {
  name           = "dev"
  description    = "Stores development Substation configuration files"
  application_id = aws_appconfig_application.substation.id
}

# AppConfig doesn't have useful support for non-linear, non-instant deployments on AWS Lambda, so this deployment strategy is used to deploy configurations as quickly as possible
resource "aws_appconfig_deployment_strategy" "instant" {
  name                           = "Instant"
  description                    = "This strategy deploys the configuration to all targets immediately with zero bake time."
  deployment_duration_in_minutes = 0
  final_bake_time_in_minutes     = 0
  growth_factor                  = 100
  growth_type                    = "LINEAR"
  replicate_to                   = "NONE"
}

# ECR image repository for the core Substation app used in the deployment
module "ecr_substation" {
  source  = "../../../build/terraform/aws/ecr"
  name    = "substation"
  kms_arn = module.kms_substation.arn
}

# ECR image repository for the autoscaling app used in the deployment
module "ecr_autoscaling" {
  source  = "../../../build/terraform/aws/ecr"
  name    = "substation_autoscaling"
  kms_arn = module.kms_substation.arn
}

################################################
# AppConfig permissions
# all Lambda must have this policy
################################################

module "iam_appconfig_read" {
  source    = "../../../build/terraform/aws/iam"
  resources = ["${aws_appconfig_application.substation.arn}/*"]
}

module "iam_appconfig_read_attachment" {
  source = "../../../build/terraform/aws/iam_attachment"
  id     = "substation_appconfig_read"
  policy = module.iam_appconfig_read.appconfig_read_policy
  roles = [
    # add all Lambda that will read application profiles
  ]
}

################################################
# KMS read permissions
# All Lambda must have this policy
################################################

module "iam_kms_read" {
  source = "../../../build/terraform/aws/iam"
  resources = [
    module.kms_substation.arn,
  ]
}

module "iam_kms_read_attachment" {
  source = "../../../build/terraform/aws/iam_attachment"
  id     = "substation_kms_read"
  policy = module.iam_kms_read.kms_read_policy
  roles = [
    # add all resources that use encryption
  ]
}

################################################
# KMS write permissions
# All Lambda must have this policy
################################################

module "iam_kms_write" {
  source = "../../../build/terraform/aws/iam"
  resources = [
    module.kms_substation.arn,
  ]
}

module "iam_kms_write_attachment" {
  source = "../../../build/terraform/aws/iam_attachment"
  id     = "substation_kms_write"
  policy = module.iam_kms_write.kms_write_policy
  roles = [
    # add all resources that use encryption
  ]
}