P5-4836 deploy api to production (new hostname)

This commit is contained in:
Niklas Fondberg
2020-02-27 13:06:58 +01:00
committed by GitHub
parent d2c567a7cd
commit b08aa76acc
9 changed files with 677 additions and 20 deletions
+1
View File
@@ -3,3 +3,4 @@
venv/ venv/
*.sublime-* *.sublime-*
ideas.py ideas.py
.fab_tasks~
+8
View File
@@ -0,0 +1,8 @@
FROM tiangolo/uwsgi-nginx-flask:python3.6
COPY ./requirements.txt /app
RUN pip install -r requirements.txt
COPY . /app/
COPY ./wsgi.py /app/main.py
RUN rm /app/wsgi.py
+18
View File
@@ -0,0 +1,18 @@
publish-to-staging:
@current_branch=$$(git rev-parse --abbrev-ref HEAD); \
git branch -D staging 2>/dev/null; \
git checkout -b staging; \
git merge $$current_branch && \
git push -f origin staging && \
git checkout $$current_branch; \
echo Pushed $$current_branch to staging
sync-master-to-staging:
@current_branch=$$(git rev-parse --abbrev-ref HEAD); \
git branch -D staging 2>/dev/null; \
git checkout master && \
git pull origin master && \
git checkout -b staging && \
git push -f origin staging && \
git checkout $$current_branch && \
echo Pushed master to staging
+1 -1
View File
@@ -5,7 +5,7 @@ mod = Blueprint("server", __name__)
@mod.route("/", methods=["GET"]) @mod.route("/", methods=["GET"])
def status(): def status():
data = {"version": "0.0.1"} data = {"version": "0.0.2"}
return jsonify(data) return jsonify(data)
+92
View File
@@ -0,0 +1,92 @@
##
# Example:
# make create-stack GITHUB_TOKEN=xxxxx ENVIRONMENT_NAME=staging STACK_NAME=api
# make create-stack GITHUB_TOKEN=xxxxx ENVIRONMENT_NAME=production STACK_NAME=api
#
# # make update-stack ENVIRONMENT_NAME=staging STACK_NAME=api
##
GITHUB_REPO := api2
GITHUB_USER := Photowall
# HOSTED_ZONE=photowall.com default in the template
# Cert ARN for the hosted zone
CERTIFICATE_ARN='arn:aws:acm:eu-west-1:954747537408:certificate/1278df32-006d-48a4-abd6-2bfccabb11fd'
DB_SECURITY_GROUP_ID_PRODUCTION=sg-0b5bafc1e0a97e848
DB_SECURITY_GROUP_ID_STAGING=sg-001b3667edf19e1ce
AWS_REGION=$(shell aws configure get region)
AWS_ACCOUNT_ID=$(shell aws sts get-caller-identity --query Account --output text)
checkdef = $(if $(value $(1)),,$(error $(1) not set))
DOCKER_IMAGE=$(AWS_ACCOUNT_ID).dkr.ecr.$(AWS_REGION).amazonaws.com/$(STACK_NAME)-$(ENVIRONMENT_NAME)
ifeq ($(ENVIRONMENT_NAME),production)
SUBDOMAIN=$(STACK_NAME)
GITHUB_BRANCH=master
DB_SECURITY_GROUP_ID=$(DB_SECURITY_GROUP_ID_PRODUCTION)
CPU_SIZE=1024
MEMORY_SIZE=4GB
else
SUBDOMAIN=$(STACK_NAME)-$(ENVIRONMENT_NAME)
GITHUB_BRANCH=$(ENVIRONMENT_NAME)
DB_SECURITY_GROUP_ID=$(DB_SECURITY_GROUP_ID_STAGING)
CPU_SIZE=512
MEMORY_SIZE=2GB
endif
check-create-initial-ecr-image:
@echo Checking for inital image $(DOCKER_IMAGE)
@aws ecr list-images --repository-name $(STACK_NAME)-$(ENVIRONMENT_NAME) 2>/dev/null | grep imageTag | grep -q latest; \
status=$$?; \
if [ $$status != 0 ]; \
then \
echo ""; \
echo "ECR Repo for initial image does not exist, creating"; \
echo ""; \
aws ecr create-repository --repository $(STACK_NAME)-$(ENVIRONMENT_NAME); \
$$(aws ecr get-login --no-include-email --region eu-west-1); \
docker pull nginx; \
docker tag nginx $(AWS_ACCOUNT_ID).dkr.ecr.$(AWS_REGION).amazonaws.com/$(STACK_NAME)-$(ENVIRONMENT_NAME):latest; \
docker push $(AWS_ACCOUNT_ID).dkr.ecr.$(AWS_REGION).amazonaws.com/$(STACK_NAME)-$(ENVIRONMENT_NAME):latest; \
echo ""; \
fi
check-create-variables-set:
$(call checkdef,STACK_NAME)
$(call checkdef,ENVIRONMENT_NAME)
$(call checkdef,GITHUB_TOKEN)
$(call checkdef,GITHUB_USER)
$(call checkdef,GITHUB_REPO)
create-stack: check-create-variables-set check-create-initial-ecr-image
aws cloudformation create-stack --stack-name $(STACK_NAME)-$(ENVIRONMENT_NAME) --template-body file://ecs-service.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--parameters ParameterKey="EnvironmentName",ParameterValue="$(ENVIRONMENT_NAME)" \
ParameterKey="Image",ParameterValue="$(DOCKER_IMAGE)" \
ParameterKey="Subdomain",ParameterValue="$(SUBDOMAIN)" \
ParameterKey="Certificate",ParameterValue="$(CERTIFICATE_ARN)" \
ParameterKey="DatabaseSecurityGroup",ParameterValue="$(DB_SECURITY_GROUP_ID)" \
ParameterKey="GitHubRepo",ParameterValue="$(GITHUB_REPO)" \
ParameterKey="GitHubUser",ParameterValue="$(GITHUB_USER)" \
ParameterKey="GitHubBranch",ParameterValue="$(GITHUB_BRANCH)" \
ParameterKey="GitHubToken",ParameterValue="$(GITHUB_TOKEN)" \
ParameterKey="CpuSize",ParameterValue="$(CPU_SIZE)" \
ParameterKey="MemorySize",ParameterValue="$(MEMORY_SIZE)"
update-stack:
$(call checkdef,STACK_NAME)
$(call checkdef,ENVIRONMENT_NAME)
aws cloudformation update-stack --stack-name $(STACK_NAME)-$(ENVIRONMENT_NAME) --template-body file://ecs-service.yaml \
--capabilities CAPABILITY_NAMED_IAM \
--parameters ParameterKey="EnvironmentName",UsePreviousValue=true \
ParameterKey="Image",UsePreviousValue=true \
ParameterKey="Subdomain",UsePreviousValue=true \
ParameterKey="Certificate",UsePreviousValue=true \
ParameterKey="DatabaseSecurityGroup",,UsePreviousValue=true \
ParameterKey="GitHubRepo",UsePreviousValue=true \
ParameterKey="GitHubUser",UsePreviousValue=true \
ParameterKey="GitHubBranch",UsePreviousValue=true \
ParameterKey="GitHubToken",UsePreviousValue=true \
ParameterKey="CpuSize",ParameterValue="$(CPU_SIZE)" \
ParameterKey="MemorySize",ParameterValue="$(MEMORY_SIZE)"
+503
View File
@@ -0,0 +1,503 @@
AWSTemplateFormatVersion: 2010-09-09
Description: CloudFormation template for a full E2E ECS service with CI/CD on Fargate.
Parameters:
VPC:
Type: AWS::EC2::VPC::Id
Default: vpc-6f596904
Description: The id of the VPC
SubnetA:
Type: AWS::EC2::Subnet::Id
Default: subnet-6e596905
Description: The id of the first subnet
SubnetB:
Type: AWS::EC2::Subnet::Id
Default: subnet-6d596906
Description: The id of the second subnet
DatabaseSecurityGroup:
Type: String
Description: Security group id to access the database
Image:
Type: String
# Docker image for this service. It must have a latest tag
# Example 260851616142.dkr.ecr.eu-west-1.amazonaws.com/nginx
EnvironmentName:
Type: String
Description: Name of env such as staging or production
# CPU
# 256 (.25 vCPU) - Available memory values: 0.5GB, 1GB, 2GB
# 512 (.5 vCPU) - Available memory values: 1GB, 2GB, 3GB, 4GB
# 1024 (1 vCPU) - Available memory values: 2GB, 3GB, 4GB, 5GB, 6GB, 7GB, 8GB
# 2048 (2 vCPU) - Available memory values: Between 4GB and 16GB in 1GB increments
# 4096 (4 vCPU) - Available memory values: Between 8GB and 30GB in 1GB increments
CpuSize:
Type: Number
# Memory
# 0.5GB, 1GB, 2GB - Available cpu values: 256 (.25 vCPU)
# 1GB, 2GB, 3GB, 4GB - Available cpu values: 512 (.5 vCPU)
# 2GB, 3GB, 4GB, 5GB, 6GB, 7GB, 8GB - Available cpu values: 1024 (1 vCPU)
# Between 4GB and 16GB in 1GB increments - Available cpu values: 2048 (2 vCPU)
# Between 8GB and 30GB in 1GB increments - Available cpu values: 4096 (4 vCPU)
MemorySize:
Type: String
ContainerPort:
Type: Number
Default: 80
LoadBalancerPort:
Type: Number
Default: 443
HealthCheckPath:
Type: String
Default: /
Certificate:
Type: String
# Update with the certificate ARN from Certificate Manager, which must exist in the same region.
HostedZoneName:
Type: String
Default: photowall.com
Subdomain:
Type: String
# for autoscaling
MinContainers:
Type: Number
Default: 1
# for autoscaling
MaxContainers:
Type: Number
Default: 4
# target CPU utilization (%)
AutoScalingTargetValue:
Type: Number
Default: 50
# Github info for code pipeline
GitHubRepo:
Type: String
GitHubBranch:
Type: String
GitHubToken:
Type: String
NoEcho: true
GitHubUser:
Type: String
Resources:
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Join ['', [!Ref 'AWS::StackName', Cluster]]
TaskDefinition:
Type: AWS::ECS::TaskDefinition
# Makes sure the log group is created before it is used.
DependsOn: LogGroup
Properties:
# Name of the task definition. Subsequent versions of the task definition are grouped together under this name.
Family: !Join ['', [!Ref 'AWS::StackName', TaskDefinition]]
# awsvpc is required for Fargate
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
Cpu: !Ref CpuSize
Memory: !Ref MemorySize
# A role needed by ECS.
# "The ARN of the task execution role that containers in this task can assume. All containers in this task are granted the permissions that are specified in this role."
# "There is an optional task execution IAM role that you can specify with Fargate to allow your Fargate tasks to make API calls to Amazon ECR."
ExecutionRoleArn: !Ref ExecutionRole
# "The Amazon Resource Name (ARN) of an AWS Identity and Access Management (IAM) role that grants containers in the task permission to call AWS APIs on your behalf."
TaskRoleArn: !Ref TaskRole
ContainerDefinitions:
- Name: !Ref AWS::StackName
Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${AWS::StackName}:latest
Environment:
- Name: DEBUG
Value: True
PortMappings:
- ContainerPort: !Ref ContainerPort
# Define which parameters should be fetched
Secrets:
- { Name: "SQLALCHEMY_DATABASE_URI", ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/SQLALCHEMY_DATABASE_URI" }
- { Name: "API_KEYS", ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/API2_API_KEYS" }
- { Name: "BERNARD_QUEUE_URL", ValueFrom: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${EnvironmentName}/BERNARD_QUEUE_URL" }
# Send logs to CloudWatch Logs
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-region: !Ref AWS::Region
awslogs-group: !Ref LogGroup
awslogs-stream-prefix: ecs
# A role needed by ECS
ExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join ['', [!Ref 'AWS::StackName', ExecutionRole]]
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
- arn:aws:iam::aws:policy/AmazonSSMReadOnlyAccess
# A role for the containers
TaskRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join ['', [!Ref 'AWS::StackName', TaskRole]]
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
# A role needed for auto scaling
AutoScalingRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Join ['', [!Ref 'AWS::StackName', AutoScalingRole]]
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceAutoscaleRole'
ContainerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: !Join ['', [!Ref 'AWS::StackName', ContainerSecurityGroup]]
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref ContainerPort
ToPort: !Ref ContainerPort
SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup
LoadBalancerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: !Join ['', [!Ref 'AWS::StackName', LoadBalancerSecurityGroup]]
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref LoadBalancerPort
ToPort: !Ref LoadBalancerPort
CidrIp: 0.0.0.0/0
Service:
Type: AWS::ECS::Service
# This dependency is needed so that the load balancer is setup correctly in time
DependsOn:
- ListenerHTTPS
Properties:
ServiceName: !Ref AWS::StackName
Cluster: !Ref Cluster
TaskDefinition: !Ref TaskDefinition
DeploymentConfiguration:
MinimumHealthyPercent: 100
MaximumPercent: 200
DesiredCount: 1
# This may need to be adjusted if the container takes a while to start up
HealthCheckGracePeriodSeconds: 30
LaunchType: FARGATE
NetworkConfiguration:
AwsvpcConfiguration:
# change to DISABLED if you're using private subnets that have access to a NAT gateway
AssignPublicIp: ENABLED
Subnets:
- !Ref SubnetA
- !Ref SubnetB
SecurityGroups:
- !Ref ContainerSecurityGroup
- !Ref DatabaseSecurityGroup
LoadBalancers:
- ContainerName: !Ref AWS::StackName
ContainerPort: !Ref ContainerPort
TargetGroupArn: !Ref TargetGroup
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 10
# will look for a 200 status code by default unless specified otherwise
HealthCheckPath: !Ref HealthCheckPath
HealthCheckTimeoutSeconds: 5
UnhealthyThresholdCount: 2
HealthyThresholdCount: 2
Name: !Join ['', [!Ref 'AWS::StackName', TargetGroup]]
Port: !Ref ContainerPort
Protocol: HTTP
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: 60 # default is 300
TargetType: ip
VpcId: !Ref VPC
ListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref TargetGroup
Type: forward
LoadBalancerArn: !Ref LoadBalancer
Port: !Ref LoadBalancerPort
Protocol: HTTPS
Certificates:
- CertificateArn: !Ref Certificate
LoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
LoadBalancerAttributes:
# this is the default, but is specified here in case it needs to be changed
- Key: idle_timeout.timeout_seconds
Value: 60
Name: !Join ['', [!Ref 'AWS::StackName', LoadBalancer]]
# "internal" is also an option
Scheme: internet-facing
SecurityGroups:
- !Ref LoadBalancerSecurityGroup
Subnets:
- !Ref SubnetA
- !Ref SubnetB
DNSRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneName: !Join ['', [!Ref HostedZoneName, .]]
Name: !Join ['', [!Ref Subdomain, ., !Ref HostedZoneName, .]]
Type: A
AliasTarget:
DNSName: !GetAtt LoadBalancer.DNSName
HostedZoneId: !GetAtt LoadBalancer.CanonicalHostedZoneID
LogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Join ['', [/ecs/, !Ref 'AWS::StackName', TaskDefinition]]
AutoScalingTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MinCapacity: !Ref MinContainers
MaxCapacity: !Ref MaxContainers
ResourceId: !Join ['/', [service, !Ref Cluster, !GetAtt Service.Name]]
ScalableDimension: ecs:service:DesiredCount
ServiceNamespace: ecs
# "The Amazon Resource Name (ARN) of an AWS Identity and Access Management (IAM) role that allows Application Auto Scaling to modify your scalable target."
RoleARN: !GetAtt AutoScalingRole.Arn
AutoScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Join ['', [!Ref 'AWS::StackName', AutoScalingPolicy]]
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref AutoScalingTarget
TargetTrackingScalingPolicyConfiguration:
PredefinedMetricSpecification:
PredefinedMetricType: ECSServiceAverageCPUUtilization
ScaleInCooldown: 10
ScaleOutCooldown: 10
# Keep things at or lower than 50% CPU utilization, for example
TargetValue: !Ref AutoScalingTargetValue
## Deployment pipeline below
CodeBuildServiceRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: codebuild.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Resource: "*"
Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
- ecr:GetAuthorizationToken
- Resource: !Sub arn:aws:s3:::${ArtifactBucket}/*
Effect: Allow
Action:
- s3:GetObject
- s3:PutObject
- s3:GetObjectVersion
- Resource: !Sub arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/${AWS::StackName}
Effect: Allow
Action:
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:BatchCheckLayerAvailability
- ecr:PutImage
- ecr:InitiateLayerUpload
- ecr:UploadLayerPart
- ecr:CompleteLayerUpload
CodePipelineServiceRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: codepipeline.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: root
PolicyDocument:
Version: 2012-10-17
Statement:
- Resource:
- !Sub arn:aws:s3:::${ArtifactBucket}/*
Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:GetObjectVersion
- s3:GetBucketVersioning
- Resource: "*"
Effect: Allow
Action:
- ecs:List*
- ecs:Describe*
- ecs:RegisterTaskDefinition
- ecs:UpdateService
- codebuild:StartBuild
- codebuild:BatchGetBuilds
- iam:PassRole
ArtifactBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
Artifacts:
Type: CODEPIPELINE
Source:
Type: CODEPIPELINE
BuildSpec: |
version: 0.2
phases:
pre_build:
commands:
- $(aws ecr get-login --no-include-email)
- TAG="$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | head -c 8)"
- IMAGE_URI="${REPOSITORY_URI}:${TAG}"
- IMAGE_LATEST_URI="${REPOSITORY_URI}:latest"
build:
commands:
- docker build --tag "$IMAGE_URI" .
- docker tag "$IMAGE_URI" "$IMAGE_LATEST_URI"
post_build:
commands:
- docker push "$IMAGE_URI"
- docker push "$IMAGE_LATEST_URI"
- printf '[{"name":"%s","imageUri":"%s"}]' "$IMAGE_NAME" "$IMAGE_LATEST_URI" > images.json
artifacts:
files: images.json
Environment:
ComputeType: BUILD_GENERAL1_SMALL
Image: aws/codebuild/docker:17.09.0
Type: LINUX_CONTAINER
EnvironmentVariables:
- Name: AWS_DEFAULT_REGION
Value: !Ref AWS::Region
- Name: REPOSITORY_URI
Value: !Ref Image
- Name: IMAGE_NAME
Value: !Ref AWS::StackName
Name: !Ref AWS::StackName
ServiceRole: !Ref CodeBuildServiceRole
Pipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
RoleArn: !GetAtt CodePipelineServiceRole.Arn
Name: !Join ['', [!Ref 'AWS::StackName', Pipeline]]
ArtifactStore:
Type: S3
Location: !Ref ArtifactBucket
Stages:
- Name: Source
Actions:
- Name: App
ActionTypeId:
Category: Source
Owner: ThirdParty
Version: 1
Provider: GitHub
Configuration:
Owner: !Ref GitHubUser
Repo: !Ref GitHubRepo
Branch: !Ref GitHubBranch
OAuthToken: !Ref GitHubToken
OutputArtifacts:
- Name: App
RunOrder: 1
- Name: Build
Actions:
- Name: Build
ActionTypeId:
Category: Build
Owner: AWS
Version: 1
Provider: CodeBuild
Configuration:
ProjectName: !Ref CodeBuildProject
InputArtifacts:
- Name: App
OutputArtifacts:
- Name: BuildOutput
RunOrder: 1
- Name: Deploy
Actions:
- Name: Deploy
ActionTypeId:
Category: Deploy
Owner: AWS
Version: 1
Provider: ECS
Configuration:
ClusterName: !Ref Cluster
ServiceName: !Ref Service
FileName: images.json
InputArtifacts:
- Name: BuildOutput
RunOrder: 1
# What outputs to expose
Outputs:
Endpoint:
Description: Endpoint
Value: !Join ['', ['https://', !Ref DNSRecord]]
Service:
Value: Service
PipelineUrl:
Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline}
ContainerSecurityGroup:
Value: !Ref ContainerSecurityGroup
TaskDefinition:
Value: !Ref TaskDefinition
+21
View File
@@ -0,0 +1,21 @@
version: '3.2'
services:
api22:
build:
context: ./
dockerfile: Dockerfile
container_name: api2.uwsgi.web
hostname: api2-uwsgi.local
ports:
- "1881:80"
environment:
- SQLALCHEMY_DATABASE_URI=postgresql://fondberg:@docker.for.mac.localhost/photowall
- API_KEYS=[]
- DEBUG=True
# - SQLALCHEMY_TRACK_MODIFICATIONS=True # change in prestart.sh
networks:
default:
external:
name: photowall-docker-network
Vendored
+18 -19
View File
@@ -1,24 +1,23 @@
from fabric.api import * from fabric.api import env, lcd, local, abort
env.user = 'ubuntu' def basic_environment_settings():
env.key_filename = '~/.ssh/ukad.pem' env.stack_name = 'api'
env.hosts = ( def staging():
'ec2-52-50-174-196.eu-west-1.compute.amazonaws.com', #api2-dev basic_environment_settings()
) env.environment = 'staging'
def production():
basic_environment_settings()
env.environment = 'production'
def cloudformation_update():
if env.environment != 'staging':
abort('Only staging is deployed soo far')
with lcd('./cloudformation/'):
local('make update-stack ENVIRONMENT_NAME={0} STACK_NAME={1}'.format(env.environment, env.stack_name))
def deploy(): def deploy():
branch = local('git rev-parse --abbrev-ref HEAD', capture=True) if env.environment != 'staging':
local('git archive --format tar.gz -o /tmp/api.tar.gz {0}'.format(branch), capture=False) abort('Local deploy to staging only. Production deploy is automatic when merging to master.')
put('/tmp/api.tar.gz', '/tmp/api.tar.gz') local('make publish-to-staging')
with warn_only():
sudo('service nginx stop')
sudo('service api-uwsgi stop')
with cd('/srv/api'):
run('tar xzf /tmp/api.tar.gz')
run('rm /tmp/api.tar.gz')
with warn_only():
sudo('service api-uwsgi start')
sudo('service nginx start')
local('rm /tmp/api.tar.gz')
+15
View File
@@ -0,0 +1,15 @@
echo "SQLALCHEMY_DATABASE_URI = '$SQLALCHEMY_DATABASE_URI'" > /app/config.py
echo "SQLALCHEMY_TRACK_MODIFICATIONS = True" >> /app/config.py
echo "API_KEYS = $API_KEYS" >> /app/config.py
echo "BERNARD_QUEUE_URL = '$BERNARD_QUEUE_URL'" >> /app/config.py
if [ -z "$DEBUG" ]
then
echo "DEBUG = False" >> /app/config.py
else
echo "DEBUG = True" >> /app/config.py
echo "SQLALCHEMY_ENGINE_OPTIONS = {" >> /app/config.py
echo ' "pool_pre_ping": True,' >> /app/config.py
echo ' "pool_recycle": 300,' >> /app/config.py
echo '} ' >> /app/config.py
fi