Package: lizzy
LizzyLizzy is a wrapper aroundSenza: a command line deployment tool for
creating and executing AWSCloudFormationtemplates. With Lizzy,
autonomous teams can useSenza, within theircontinuous deliverypipelines, to deploy new versions of their apps to a team-specific AWS
account. Lizzy can be deployed to an AWS account, then it’s REST API
can be used to deploy new apps to that account.Why LizzyAtZalando, development teams have their own AWS accounts so they
can work autonomously. One team (Continuous Delivery) is responsible
for maintaining theJenkinsesof all other Zalando teams. This allows
teams to focus on theirOKR’sinstead of spending their time
configuringJenkinsor creating their own continuous deployment
tools. For Zalando, Lizzy helps makecontinuous deliveryusing our
Jenkins-as-a-Service setup possible. Without Lizzy teams would need
to save AWS credentials to their Jenkins instance.If your team is interested in working withimmutable stackson AWS
you can useSenzato create and manage your stacks usingCloudFormation. Lizzy is an additional tool that provides a
deployment API to be used by yourcontinuous deliverypipeline to
run Senza commands. Lizzy can be used along with any code integration
tool likeJenkins,TravisCI,CircleCI, etc.How Lizzy WorksLizzy consists of the Lizzy Agent — a REST API service — and theLizzy-Clientcommand line tool.The Lizzy Agent is a web application deployed in a team’s AWS account
and granted access to create new CloudFormation stacks through a REST
API. All requests are authenticated usingOAuth2bearer tokens.Lizzy-Clientmimics the usage ofSenza’s commands and transforms
them into HTTP requests, which are then sent to Lizzy Agent’s REST
API.Who Uses LizzyMany Zalando teams use Lizzy in production to deliver high-quality
services that power thefastest-growingonline fashion platform in
Europe. If you want to know more about how Zalando uses Lizzy, please
read our blog postContinuous Delivery pipelines of ghe-backups with
Lizzy.How to Run Lizzy LocallyThis repository includes aDockerfilethat you can use to build an
image locally using the command:$dockerbuild-tlizzy:dev.HintIf you clone this repository, the “scm-source.json” file
will be missing. To know more about what is in this file,
please read theSTUPS documentation. We havetoolsthat can generate this file for you.After the image is built, it will be available with the tag
“lizzy:dev”. You will also need to specify some environment variables
for Lizzy to use. Here is an “example.cfg” file:TOKEN_URL=https://token.auth.example.com/oauth2/access_tokenTOKENINFO_URL=https://info.auth.example.com/oauth2/tokeninfoALLOWED_USERS=['robotusername','myusername']DEPLOYER_SCOPE=deployerLOG_LEVEL=DEBUGYou also need to configure theAWS credentialslocally in your
machine under~/.aws. After that, you can run the Lizzy image with
the command:$dockerrun--rm-p8080:8080--env-fileenvironment.cfg-v~/.aws:/.aws--namelizzy-u999-itlizzy:devThe application will be available by default at the port8080, which
is usually accessible athttp://127.0.0.1:8080. It depends on how
you’ve configured Docker locally. ASwagger/OpenAPI consoleis
available athttp://127.0.0.1:8080/api/ui/#/default.Deploying to AWSThere are many ways to deploy Lizzy to AWS. At Zalando we useSTUPS, which provides a convenient and audit-compliant
Platform-as-a-Service (PaaS). An example of theSenza definitionto
deploy Lizzy:SenzaInfo:StackName:lizzyParameters:-ImageVersion:Description:"Dockerimageversionoflizzy."SenzaComponents:-Configuration:Type:'Senza::StupsAutoConfiguration'-AppServer:Type:Senza::TaupageAutoScalingGroupAssociatePublicIpAddress:falseElasticLoadBalancer:AppLoadBalancerIamRoles:['app-lizzy']InstanceType:t2.nanoSecurityGroups:['app-lizzy']TaupageConfig:application_version:'{{Arguments.ImageVersion}}'environment:ALLOWED_USER_PATTERN:"^(jenkins-slave-\\w+)$"DEPLOYER_SCOPE:myscopeLANG:C.UTF-8LC_ALL:C.UTF-8LOG_LEVEL:DEBUGREGION:'{{AccountInfo.Region}}'TOKEN_URL:'https://token.auth.example.com/oauth2/access_token'TOKENINFO_URL:'https://info.auth.example.com/oauth2/tokeninfo'health_check_path:/api/swagger.jsonports:{8080:8080}runtime:Dockersource:'lizzy:{{Arguments.ImageVersion}}'-AppLoadBalancer:HTTPPort:8080HealthCheckPath:/api/swagger.jsonScheme:internet-facingSecurityGroups:['app-lizzy-lb']Type:Senza::WeightedDnsElasticLoadBalancerAccess Control for LizzyTo create new CloudFormation stacks, Lizzy applications need access to
CloudFormation plus some other services from Amazon’s API. You will
need to specify theIAM rolein a manner like:{"Statement":[{"Action":["iam:*","cloudformation:*","ec2:*","route53:*","elasticloadbalancing:*","cloudwatch:*","elasticache:*","acm:*","autoscaling:*","sqs:*"],"Effect":"Allow","Resource":"*"}],"Version":"2012-10-17"}That is the minimal configuration Lizzy needs to run Senza commands
successfully. Other statements might be included in this configuration.ConfigurationLizzy uses the following environment variables for configuration:NAMEDESCRIPTIONDEFAULTALLOWED_USERSList of users that can use LizzyALLOWED_USER_PATTERNDefines a regular expression to match
usernames allowed to use LizzyDEPLOYER_SCOPEOAUTH scope needed to deployLOG_LEVELSets the minimum log levelINFOLOG_FORMATSets the log format (human or default)defaultREGIONAWS Region to useeu-west-1SENTRY_DSNSentry URL with client keysTOKEN_URLURL to get a new tokenTOKENINFO_URLURL to validate the tokenConfiguring Access to LizzyThere are two environment variables for configuring who is allowed to
perform successful calls to the Lizzy Agent. You must use one (and
ONLY one) of them: EitherALLOWED_USERSorALLOWED_USER_PATTERN. To choose which one fits your use case, you
first need to understand what they do.ALLOWED_USERS: List of specific usernames that can access
Lizzy. Use it when you know the exact usernames of the clients you
want to give access to your service.ALLOWED_USER_PATTERN: Regular expression that should match the
username of the clients that are going to call the Lizzy API. Use it
when you know that the username should start with some pattern, likestups_.+.Those variables are mutually exclusive. Again: use only one of them.Authentication ServiceTheTOKEN_URLenvironment variable should point to the service
that provides OAuth tokens. At Zalando, we use the open-sourcePlanB
providerfor that. TheTOKENINFO_URLenvironment variable should
point to the service that stores information about the tokens. To
store the OAuth2 token information, we usePlanB token info, also
developed by Zalando. If you do not have any OAuth2 infrastructure,
please take a look at those projects.Contributing to LizzyWe welcome your ideas, issues, and pull requests. Just follow the
usual/standardGitHub practices.LicenseCopyright 2015 Zalando SELicensed under the Apache License, Version 2.0 (the “License”);
you may not use this file except in compliance with the License.
You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.