genericsuite-be-scripts
Version:
GenericSuite Scripts (backend version)
187 lines (168 loc) • 6.56 kB
YAML
AWSTemplateFormatVersion: '2010-09-09'
Description: Deploy GenericSuite application domain for the EC2 instances (SSL Certificate and Route53 domain)
Parameters:
DomainName:
Description: Domain name for the ALB
Type: String
AppName:
Description: application name
Type: String
AppStage:
Description: application stage (qa, prod, staging, demo, dev)
Type: String
HostedZoneId:
Description: The ID of the hosted zone where the domain is managed
Type: AWS::Route53::HostedZone::Id
Resources:
Route53RecordSet:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneId: !Ref HostedZoneId
Name: !Ref DomainName
Type: A
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-route53.html
TTL: '60'
ResourceRecords:
- 192.168.0.1
- 192.168.0.2
AppSSLCertificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: !Ref DomainName
ValidationMethod: DNS
Tags:
- Key: App
Value: !Ref AppName
- Key: Stage
Value: !Ref AppStage
- Key: Name
Value: !Sub "${AppName}-${AppStage}-ssl-certificate"
GetCertificateValidationResource:
Type: Custom::GetCertificateValidation
Properties:
ServiceToken: !GetAtt GetCertificateValidationFunction.Arn
CertificateArn: !Ref AppSSLCertificate
GetCertificateValidationFunction:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.11
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
if event['RequestType'] == 'Delete':
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
return
certificate_arn = event['ResourceProperties']['CertificateArn']
acm_client = boto3.client('acm')
try:
response = acm_client.describe_certificate(CertificateArn=certificate_arn)
validation_options = response['Certificate']['DomainValidationOptions']
for option in validation_options:
if 'ResourceRecord' in option:
record = option['ResourceRecord']
cfnresponse.send(event, context, cfnresponse.SUCCESS, {
'Name': record['Name'],
'Type': record['Type'],
'Value': record['Value']
})
return
cfnresponse.send(event, context, cfnresponse.FAILED, {
'Reason': 'No validation records found'
})
except Exception as e:
cfnresponse.send(event, context, cfnresponse.FAILED, {
'Reason': str(e)
})
CreateCNAMERecordResource:
Type: Custom::CreateCNAMERecord
Properties:
ServiceToken: !GetAtt CreateCNAMERecordFunction.Arn
HostedZoneId: !Ref HostedZoneId
RecordName: !GetAtt GetCertificateValidationResource.Name
RecordType: !GetAtt GetCertificateValidationResource.Type
RecordValue: !GetAtt GetCertificateValidationResource.Value
CreateCNAMERecordFunction:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.11
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
if event['RequestType'] == 'Delete':
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
return
hosted_zone_id = event['ResourceProperties']['HostedZoneId']
record_name = event['ResourceProperties']['RecordName']
record_type = event['ResourceProperties']['RecordType']
record_value = event['ResourceProperties']['RecordValue']
route53_client = boto3.client('route53')
try:
response = route53_client.change_resource_record_sets(
HostedZoneId=hosted_zone_id,
ChangeBatch={
'Changes': [
{
'Action': 'UPSERT',
'ResourceRecordSet': {
'Name': record_name,
'Type': record_type,
'TTL': 300,
'ResourceRecords': [{'Value': record_value}]
}
}
]
}
)
cfnresponse.send(event, context, cfnresponse.SUCCESS, {
'Message': 'CNAME record created successfully'
})
except Exception as e:
cfnresponse.send(event, context, cfnresponse.FAILED, {
'Reason': str(e)
})
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: ACMandRoute53Access
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- acm:DescribeCertificate
- route53:ChangeResourceRecordSets
Resource: '*'
Outputs:
CertificateArn:
Description: ARN of the created SSL Certificate
Value: !Ref AppSSLCertificate
Export:
Name: !Sub "${AWS::StackName}-CertificateArn"
Route53RecordSetId:
Description: ID of the created Route53 Record Set
Value: !Ref Route53RecordSet
Export:
Name: !Sub "${AWS::StackName}-Route53RecordSetId"
DomainName:
Description: Domain name for the ALB
Value: !Ref DomainName
Export:
Name: !Sub "${AWS::StackName}-DomainName"