Skip to content

CloudFormation Template Rules

In order to deploy your application using Tibica Installer, it has to comply with the set of rules. These rules are check agains the CloudFormation template produced by your stack (whether you are using Serverless Framework or AWS CDK).

Rules

  1. Tags

    Your application must have the following tags:

    KeyValue
    tibica-applicationSERVICE_NAME
    tibica-customerCUSTOMER_ID
    tibica-parentSTACK_NAME

    SERVICE_NAME is the name of your application starting with tibica- (for example, tibica-cloud-git). CUSTOMER_ID is the id of the customer on which your application is installed. You will get it as an environment variable in your application. STACK_NAME is the name of your stack. It consists of your SERVICE_NAME and CUSTOMER_ID split by a dash: {SERVICE_NAME}-{CUSTOMER_ID}.

    Please note that we will not be able to manage applications that do not have these tags or have names that do not start with tibica-.

    You can read more about the values for the tags in the Vendor Application Structure Readme.md file.

  2. IAM Policies

    We strictly prohibit the use of wildcards (*) in IAM policies, as well as the use of the AWS-managed AdministratorAccess policy.

  3. Serverless Resources Only

    We prohibit the deployment of non-serverless resources on our accounts. This includes but is not limited to EC2 instances, ECS clusters, EKS clusters, RDS databases, Elasticache clusters, Elastic Beanstalk applications, Redshift clusters, etc.

  4. Info Endpoint for API Gateway

    If you are deploying an API Gateway, it must have an endpoint that returns information about the application at /info route. This endpoint should be accessible without any authentication. Here’s an example of the response if you’re using AWS CDK for Python:

import json
import config
from datetime import datetime
from decimal import Decimal
from typing import Any
from aws_cdk import aws_apigateway as api_gw
class Encoder(json.JSONEncoder):
def default(self, o: Any) -> Any:
if isinstance(o, datetime):
return o.isoformat()
elif isinstance(o, Decimal):
if o % 1 == 0:
return int(o)
else:
return float(o)
return super().encode(o)
all_info_resource = api.root.add_resource("info")
template = json.dumps(
{
"installedVersion": config.CustomVersion,
"installedVersionHash": config.CustomHashVersion,
"tags": {
config.TIBICA_CUSTOMER: config.CUSTOMER_ID,
config.TIBICA_APPLICATION: config.SERVICE_NAME,
config.TIBICA_PARENT: config.STACK_NAME,
},
"region": config.REGION,
"accountIdPool": config.ACCOUNT_ID_POOL,
"domainName": config.DOMAIN_NAME,
"aliasName": config.ALIAS_NAME,
"hostedZonesId": config.HOSTED_ZONES_ID,
"DNSCertificate": config.DNS_CERTIFICATE,
"stackName": config.STACK_NAME,
},
default=Encoder().default,
)
# methods
all_info_resource.add_method(
"GET",
operation_name="applicationInfo",
integration=api_gw.MockIntegration(
integration_responses=[
{
"statusCode": "200",
"responseParameters": {
"method.response.header.Access-Control-Allow-Origin": "'*'",
},
"responseTemplates": {"application/json": template}
}
],
passthrough_behavior=api_gw.PassthroughBehavior.NEVER,
request_templates={"application/json": '{"statusCode": 200}'},
),
api_key_required=False,
method_responses=[
api_gw.MethodResponse(
status_code="200",
response_parameters={
"method.response.header.Access-Control-Allow-Origin": True,
"method.response.header.Access-Control-Allow-Headers": True,
"method.response.header.Access-Control-Allow-Methods": True,
},
response_models={
"application/json": api_gw.Model(
self,
"tibica_all_info_models",
rest_api=api,
content_type="application/json",
schema=api_gw.JsonSchema(
type=api_gw.JsonSchemaType.OBJECT,
properties={
"installedVersion": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Version of lambda",
),
"installedHashVersion": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Hash version of lambda",
),
"tags": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.OBJECT,
properties={
config.TIBICA_CUSTOMER: api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Customer id",
),
config.TIBICA_APPLICATION: api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Application name",
),
config.TIBICA_PARENT: api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Parent stack name",
),
},
),
"region": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Region for deployment",
),
"accountIdPool": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Account id for pool",
),
"domainName": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Domain name",
),
"aliasName": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Alias name",
),
"hostedZonesId": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Hosted zones id",
),
"DNSCertificate": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="DNS certificate",
),
"stackName": api_gw.JsonSchema(
type=api_gw.JsonSchemaType.STRING,
description="Stack name",
),
},
),
)
},
)
],
)