typescript aws

pull/235/head
mdugdale 2021-03-27 22:52:27 +00:00
parent a56ed139c2
commit b1ff94ae07
2 changed files with 501 additions and 0 deletions

179
dist/cloudformation-stack-ttl.yml vendored 100644
View File

@ -0,0 +1,179 @@
AWSTemplateFormatVersion: '2010-09-09'
Description: Schedule automatic deletion of CloudFormation stacks
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Input configuration
Parameters:
- StackName
- TTL
ParameterLabels:
StackName:
default: Stack name
TTL:
default: Time-to-live
Parameters:
BUILDID:
Type: String
Default: ''
StackName:
Type: String
Description: Stack name that will be deleted.
TTL:
Type: Number
Description: Time-to-live in minutes for the stack.
Resources:
DeleteCFNLambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: ["lambda.amazonaws.com"]
Action: "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: !Sub "DeleteCFNLambdaExecutionRole-${StackName}"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "arn:aws:logs:*:*:*"
- Effect: "Allow"
Action:
- "cloudformation:DeleteStack"
Resource: !Sub "arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${StackName}/*"
DeleteCFNLambda:
Type: "AWS::Lambda::Function"
DependsOn:
- DeleteCFNLambdaExecutionRole
Properties:
FunctionName: !Sub "DeleteCFNLambda-${StackName}"
Code:
ZipFile: |
import boto3
import os
import json
stack_name = os.environ['stackName']
def delete_cfn(stack_name):
try:
cfn = boto3.resource('cloudformation')
stack = cfn.Stack(stack_name)
stack.delete()
return "SUCCESS"
except:
return "ERROR"
def handler(event, context):
print("Received event:")
print(json.dumps(event))
return delete_cfn(stack_name)
Environment:
Variables:
stackName: !Ref 'StackName'
Handler: "index.handler"
Runtime: "python3.6"
Timeout: "5"
Role: !GetAtt DeleteCFNLambdaExecutionRole.Arn
DeleteStackEventRule:
DependsOn:
- DeleteCFNLambda
- GenerateCronExpression
Type: "AWS::Events::Rule"
Properties:
Name: !Join [ "", [ 'DeleteStackEventRule', !Ref BUILDID ] ]
Description: Delete stack event
ScheduleExpression: !GetAtt GenerateCronExpression.cron_exp
State: "ENABLED"
Targets:
-
Arn: !GetAtt DeleteCFNLambda.Arn
Id: 'DeleteCFNLambda'
PermissionForDeleteCFNLambda:
Type: "AWS::Lambda::Permission"
Properties:
FunctionName: !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:DeleteCFNLambda-${StackName}"
Action: "lambda:InvokeFunction"
Principal: "events.amazonaws.com"
SourceArn: !GetAtt DeleteStackEventRule.Arn
BasicLambdaExecutionRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: ["lambda.amazonaws.com"]
Action: "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: !Sub "BasicLambdaExecutionRole-${StackName}"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "arn:aws:logs:*:*:*"
GenerateCronExpLambda:
Type: "AWS::Lambda::Function"
Properties:
FunctionName: !Join [ "", [ 'GenerateCronExpLambda', !Ref BUILDID ] ]
Code:
ZipFile: |
from datetime import datetime, timedelta
import os
import logging
import json
import cfnresponse
def deletion_time(ttl):
delete_at_time = datetime.now() + timedelta(minutes=int(ttl))
hh = delete_at_time.hour
mm = delete_at_time.minute
yyyy = delete_at_time.year
month = delete_at_time.month
dd = delete_at_time.day
# minutes hours day month day-of-week year
cron_exp = "cron({} {} {} {} ? {})".format(mm, hh, dd, month, yyyy)
return cron_exp
def handler(event, context):
print('Received event: %s' % json.dumps(event))
status = cfnresponse.SUCCESS
try:
if event['RequestType'] == 'Delete':
cfnresponse.send(event, context, status, {})
else:
ttl = event['ResourceProperties']['ttl']
responseData = {}
responseData['cron_exp'] = deletion_time(ttl)
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
except Exception as e:
logging.error('Exception: %s' % e, exc_info=True)
status = cfnresponse.FAILED
cfnresponse.send(event, context, status, {}, None)
Handler: "index.handler"
Runtime: "python3.6"
Timeout: "5"
Role: !GetAtt BasicLambdaExecutionRole.Arn
GenerateCronExpression:
Type: "Custom::GenerateCronExpression"
Version: "1.0"
Properties:
Name: !Sub "GenerateCronExpression-${StackName}"
ServiceToken: !GetAtt GenerateCronExpLambda.Arn
ttl: !Ref 'TTL'

322
dist/task-def-formation.yml vendored 100644
View File

@ -0,0 +1,322 @@
AWSTemplateFormatVersion: 2010-09-09
Description: >-
AWS Fargate cluster that can span public and private subnets. Supports public
facing load balancers, private internal load balancers, and both internal and
external service discovery namespaces.
Parameters:
EnvironmentName:
Type: String
Default: development
Description: 'Your deployment environment: DEV, QA , PROD'
ServiceName:
Type: String
Default: example
Description: A name for the service
ImageUrl:
Type: String
Default: nginx
Description: >-
The url of a docker image that contains the application process that will
handle the traffic for this service
ContainerPort:
Type: Number
Default: 80
Description: What port number the application inside the docker container is binding to
ContainerCpu:
Type: Number
Default: 1024
Description: How much CPU to give the container. 1024 is 1 CPU
ContainerMemory:
Type: Number
Default: 2048
Description: How much memory in megabytes to give the container
BUILDID:
Type: String
Default: ''
Command:
Type: String
Default: 'ls'
EntryPoint:
Type: String
Default: '/bin/sh'
WorkingDirectory:
Type: String
Default: '/efsdata/'
Role:
Type: String
Default: ''
Description: >-
(Optional) An IAM role to give the service's containers if the code within
needs to access other AWS resources like S3 buckets, DynamoDB tables, etc
EFSMountDirectory:
Type: String
Default: '/efsdata'
GithubToken:
Type: String
Default: '0'
UnityLicense:
Type: String
Default: '0'
UnityEmail:
Type: String
Default: '0'
UnityPassword:
Type: String
Default: '0'
UnitySerial:
Type: String
Default: '0'
AndroidKeystoreBase64:
Type: String
Default: '0'
AndroidKeystorePass:
Type: String
Default: '0'
AndroidKeyAliasPass:
Type: String
Default: '0'
AWSAccessKeyID:
Type: String
Default: '0'
AWSSecretAccessKey:
Type: String
Default: '0'
Mappings:
SubnetConfig:
VPC:
CIDR: 10.0.0.0/16
PublicOne:
CIDR: 10.0.0.0/24
PublicTwo:
CIDR: 10.0.1.0/24
Conditions:
HasCustomRole: !Not
- !Equals
- Ref: Role
- ''
Resources:
LogGroup:
Type: 'AWS::Logs::LogGroup'
Properties:
LogGroupName: !Ref ServiceName
Metadata:
'AWS::CloudFormation::Designer':
id: aece53ae-b82d-4267-bc16-ed964b05db27
SubscriptionFilter:
Type: 'AWS::Logs::SubscriptionFilter'
Properties:
FilterPattern: ''
RoleArn:
'Fn::ImportValue': !Sub '${EnvironmentName}:CloudWatchIAMRole'
LogGroupName: !Ref ServiceName
DestinationArn:
'Fn::GetAtt':
- KinesisStream
- Arn
Metadata:
'AWS::CloudFormation::Designer':
id: 7f809e91-9e5d-4678-98c1-c5085956c480
DependsOn:
- LogGroup
- KinesisStream
KinesisStream:
Type: 'AWS::Kinesis::Stream'
Properties:
Name: !Ref ServiceName
ShardCount: 1
Metadata:
'AWS::CloudFormation::Designer':
id: c6f18447-b879-4696-8873-f981b2cedd2b
GithubTokenSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'GithubToken', !Ref BUILDID ] ]
SecretString: !Ref GithubToken
UnityLicenseSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'UnityLicense', !Ref BUILDID ] ]
SecretString: !Ref UnityLicense
UnityEmailSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'UnityEmail', !Ref BUILDID ] ]
SecretString: !Ref UnityEmail
UnityPasswordSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'UnityPassword', !Ref BUILDID ] ]
SecretString: !Ref UnityPassword
UnitySerialSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'UnitySerial', !Ref BUILDID ] ]
SecretString: !Ref UnitySerial
AndroidKeystoreBase64Secret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'AndroidKeystoreBase64', !Ref BUILDID ] ]
SecretString: !Ref AndroidKeystoreBase64
AndroidKeystorePassSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'AndroidKeystorePass', !Ref BUILDID ] ]
SecretString: !Ref AndroidKeystorePass
AndroidKeyAliasPassSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'AndroidKeyAliasPass', !Ref BUILDID ] ]
SecretString: !Ref AndroidKeyAliasPass
AWSAccessKeyIDSecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'AWSAccessKeyID', !Ref BUILDID ] ]
SecretString: !Ref AWSAccessKeyID
AWSSecretAccessKeySecret:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Join [ "", [ 'AWSSecretAccessKey', !Ref BUILDID ] ]
SecretString: !Ref AWSSecretAccessKey
TaskDefinition:
Type: 'AWS::ECS::TaskDefinition'
Properties:
Family: !Ref ServiceName
Cpu: !Ref ContainerCpu
Memory: !Ref ContainerMemory
NetworkMode: awsvpc
Volumes:
- Name: efs-data
EFSVolumeConfiguration:
FilesystemId:
'Fn::ImportValue': !Sub '${EnvironmentName}:EfsFileStorageId'
TransitEncryption: ENABLED
RequiresCompatibilities:
- FARGATE
ExecutionRoleArn:
'Fn::ImportValue': !Sub '${EnvironmentName}:ECSTaskExecutionRole'
TaskRoleArn:
'Fn::If':
- HasCustomRole
- !Ref Role
- !Ref 'AWS::NoValue'
ContainerDefinitions:
- Name: !Ref ServiceName
Cpu: !Ref ContainerCpu
Memory: !Ref ContainerMemory
Image: !Ref ImageUrl
EntryPoint:
Fn::Split:
- ","
- !Ref EntryPoint
Command:
Fn::Split:
- ","
- !Ref Command
WorkingDirectory: !Ref WorkingDirectory
Environment:
- Name: ALLOW_EMPTY_PASSWORD
Value: 'yes'
MountPoints:
- SourceVolume: efs-data
ContainerPath: !Ref EFSMountDirectory
ReadOnly: false
Secrets:
- Name: 'GITHUB_TOKEN'
ValueFrom: !Ref GithubTokenSecret
- Name: 'UNITY_LICENSE'
ValueFrom: !Ref UnityLicenseSecret
- Name: 'UNITY_EMAIL'
ValueFrom: !Ref UnityEmailSecret
- Name: 'UNITY_PASSWORD'
ValueFrom: !Ref UnityPasswordSecret
- Name: 'UNITY_SERIAL'
ValueFrom: !Ref UnitySerialSecret
- Name: 'ANDROID_KEYSTORE_BASE64'
ValueFrom: !Ref AndroidKeystoreBase64Secret
- Name: 'ANDROID_KEYSTORE_PASS'
ValueFrom: !Ref AndroidKeystorePassSecret
- Name: 'AWS_ACCESS_KEY_ID'
ValueFrom: !Ref AWSAccessKeyIDSecret
- Name: 'AWS_SECRET_ACCESS_KEY'
ValueFrom: !Ref AWSSecretAccessKeySecret
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref ServiceName
awslogs-region: !Ref 'AWS::Region'
awslogs-stream-prefix: !Ref ServiceName
Metadata:
'AWS::CloudFormation::Designer':
id: dabb0116-abe0-48a6-a8af-cf9111c879a5
DependsOn:
- LogGroup
Metadata:
'AWS::CloudFormation::Designer':
dabb0116-abe0-48a6-a8af-cf9111c879a5:
size:
width: 60
height: 60
position:
x: 270
'y': 90
z: 1
embeds: []
dependson:
- aece53ae-b82d-4267-bc16-ed964b05db27
c6f18447-b879-4696-8873-f981b2cedd2b:
size:
width: 60
height: 60
position:
x: 270
'y': 210
z: 1
embeds: []
7f809e91-9e5d-4678-98c1-c5085956c480:
size:
width: 60
height: 60
position:
x: 60
'y': 300
z: 1
embeds: []
dependson:
- aece53ae-b82d-4267-bc16-ed964b05db27
- c6f18447-b879-4696-8873-f981b2cedd2b
aece53ae-b82d-4267-bc16-ed964b05db27:
size:
width: 150
height: 150
position:
x: 60
'y': 90
z: 1
embeds: []
4d2da56c-3643-46b8-aaee-e46e19f95fcc:
source:
id: 7f809e91-9e5d-4678-98c1-c5085956c480
target:
id: aece53ae-b82d-4267-bc16-ed964b05db27
z: 11
14eb957b-f094-4653-93c4-77b2f851953c:
source:
id: 7f809e91-9e5d-4678-98c1-c5085956c480
target:
id: c6f18447-b879-4696-8873-f981b2cedd2b
z: 12
85c57444-e5bb-4230-bc85-e545cd4558f6:
source:
id: dabb0116-abe0-48a6-a8af-cf9111c879a5
target:
id: aece53ae-b82d-4267-bc16-ed964b05db27
z: 13