walkthroughs/howto-mutual-tls-file-provided-by-acm/infrastructure/acmpca.yaml (219 lines of code) (raw):
Parameters:
DomainName:
Type: String
Default: 'appmesh-acm-pca-mtls.svc.cluster.local'
Description: The mesh domain name for setup of ACM PCA mTLS
EnvironmentName:
Description: An environment name that will be prefixed to resource names
Type: String
Resources:
# ---------------------------------------------------------------------------
# Create Private CA - Color Teller
# ---------------------------------------------------------------------------
AcmPcaColorTellerRootCA:
Type: AWS::ACMPCA::CertificateAuthority
Properties:
Type: ROOT
KeyAlgorithm: RSA_2048
SigningAlgorithm: SHA256WITHRSA
Subject:
CommonName: "AcmPcaColorTeller"
# ---------------------------------------------------------------------------
# Create root cert for Private CA Color Teller
# ---------------------------------------------------------------------------
AcmPcaColorTellerRootCACert:
Type: 'AWS::ACMPCA::Certificate'
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorTellerRootCA
CertificateSigningRequest: !GetAtt
- AcmPcaColorTellerRootCA
- CertificateSigningRequest
SigningAlgorithm: SHA256WITHRSA
TemplateArn: !Sub 'arn:${AWS::Partition}:acm-pca:::template/RootCACertificate/V1'
Validity:
Type: YEARS
Value: 10
# ---------------------------------------------------------------------------
# Activate Private CA Color Teller -
# Associates Root CA with Root Cert
# ---------------------------------------------------------------------------
AcmPcaColorTellerRootCAActivation:
Type: 'AWS::ACMPCA::CertificateAuthorityActivation'
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorTellerRootCA
Certificate: !GetAtt
- AcmPcaColorTellerRootCACert
- Certificate
Status: ACTIVE
# ---------------------------------------------------------------------------
# Create endpoint cert for Color Teller app mesh node
# TODO
# ---------------------------------------------------------------------------
AcmPcaColorTellerEndpointCert:
Type: AWS::CertificateManager::Certificate
DependsOn: AcmPcaColorTellerRootCAActivation
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorTellerRootCA
DomainName: !Sub 'colorteller.${DomainName}'
# ---------------------------------------------------------------------------
# Create Private CA - Color Gateway
# ---------------------------------------------------------------------------
AcmPcaColorGatewayRootCA:
Type: AWS::ACMPCA::CertificateAuthority
Properties:
Type: ROOT
KeyAlgorithm: RSA_2048
SigningAlgorithm: SHA256WITHRSA
Subject:
CommonName: "AcmPcaColorGateway"
# ---------------------------------------------------------------------------
# Create root cert for Private CA Color Gateway
# ---------------------------------------------------------------------------
AcmPcaColorGatewayRootCACert:
Type: 'AWS::ACMPCA::Certificate'
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorGatewayRootCA
CertificateSigningRequest: !GetAtt
- AcmPcaColorGatewayRootCA
- CertificateSigningRequest
SigningAlgorithm: SHA256WITHRSA
TemplateArn: !Sub 'arn:${AWS::Partition}:acm-pca:::template/RootCACertificate/V1'
Validity:
Type: YEARS
Value: 10
# ---------------------------------------------------------------------------
# Activate Private CA Color Gateway -
# Associates Root CA with Root Cert
# ---------------------------------------------------------------------------
AcmPcaColorGatewayRootCAActivation:
Type: 'AWS::ACMPCA::CertificateAuthorityActivation'
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorGatewayRootCA
Certificate: !GetAtt
- AcmPcaColorGatewayRootCACert
- Certificate
Status: ACTIVE
# ---------------------------------------------------------------------------
# Create endpoint cert for Color Gateway app mesh node
# ---------------------------------------------------------------------------
AcmPcaColorGatewayEndpointCert:
Type: AWS::CertificateManager::Certificate
DependsOn: AcmPcaColorGatewayRootCAActivation
Properties:
CertificateAuthorityArn: !Ref AcmPcaColorGatewayRootCA
DomainName: !Sub 'colorgateway.${DomainName}'
SecretCert:
Type: AWS::SecretsManager::Secret
Properties:
SecretString: |
{
"GatewayCertificate": "tempcert",
"GatewayCertificateChain": "tempcertchain",
"GatewayPrivateKey": "privatekey",
"Passphrase": "passphrase"
}
InitCertRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Action: sts:AssumeRole
ManagedPolicyArns:
- !Sub 'arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
Policies:
- PolicyName: acm-secretsmanager-access
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action: acm:ExportCertificate
Resource:
- !Ref AcmPcaColorGatewayEndpointCert
- !Ref AcmPcaColorTellerEndpointCert
- Effect: Allow
Action:
- secretsmanager:GetRandomPassword
Resource: '*'
- Effect: Allow
Action: secretsmanager:PutSecretValue
Resource: !Ref SecretCert
- Effect: Allow
Action: acm-pca:CreatePermission
Resource:
- !Ref AcmPcaColorGatewayRootCA
- !Ref AcmPcaColorTellerRootCA
InitCertFunction:
Type: AWS::Lambda::Function
Properties:
Description: Initial function to populate secrets manager from ACM
Handler: index.lambda_handler
Role: !GetAtt InitCertRole.Arn
Runtime: python3.8
Timeout: 900
Environment:
Variables:
COLOR_GATEWAY_ACM_ARN: !Ref AcmPcaColorGatewayEndpointCert
COLOR_TELLER_ACM_ARN: !Ref AcmPcaColorTellerEndpointCert
COLOR_TELLER_ACM_PCA_ARN: !Ref AcmPcaColorTellerRootCA
COLOR_GATEWAY_ACM_PCA_ARN: !Ref AcmPcaColorGatewayRootCA
AWS_ACCOUNT: !Ref 'AWS::AccountId'
SECRET: !Ref SecretCert
Code:
ZipFile: |
import json
import boto3
import base64
import os
import cfnresponse
sm = boto3.client('secretsmanager')
cm = boto3.client('acm')
pca = boto3.client('acm-pca')
gate_cm = os.environ['COLOR_GATEWAY_ACM_ARN']
teller_cm = os.environ['COLOR_TELLER_ACM_ARN']
teller_pca_cm = os.environ['COLOR_TELLER_ACM_PCA_ARN']
gateway_pca_cm = os.environ['COLOR_GATEWAY_ACM_PCA_ARN']
acc_id = os.environ['AWS_ACCOUNT']
secret = os.environ['SECRET']
def lambda_handler(event, context):
print (json.dumps(event))
if (event['RequestType'] == 'Delete') or (event['RequestType'] == 'Update'):
cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, '')
elif event['RequestType'] == 'Create':
try:
pca.create_permission(
CertificateAuthorityArn=teller_pca_cm,
Principal='acm.amazonaws.com',
SourceAccount=acc_id,
Actions=[
'IssueCertificate',
'GetCertificate',
'ListPermissions'
]
)
pca.create_permission(
CertificateAuthorityArn=gateway_pca_cm,
Principal='acm.amazonaws.com',
SourceAccount=acc_id,
Actions=[
'IssueCertificate',
'GetCertificate',
'ListPermissions'
]
)
passphrase = sm.get_random_password(ExcludePunctuation=True)['RandomPassword']
passphrase_enc = base64.b64encode(passphrase.encode('utf-8'))
cm.export_certificate(CertificateArn=teller_cm, Passphrase=passphrase_enc)
gate_rsp = cm.export_certificate(CertificateArn=gate_cm, Passphrase=passphrase_enc)
sm_value={}
sm_value['GatewayCertificate']=gate_rsp['Certificate']
sm_value['GatewayCertificateChain']=gate_rsp['CertificateChain']
sm_value['GatewayPrivateKey']=gate_rsp['PrivateKey']
sm_value['Passphrase']=passphrase
sm.put_secret_value(SecretId=secret, SecretString=json.dumps(sm_value))
cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, '')
except Exception as e:
print(e)
cfnresponse.send(event, context, cfnresponse.FAILED, {}, '')
InitCert:
Type: Custom::InitCert
Properties:
ServiceToken: !GetAtt InitCertFunction.Arn
Secret: !Ref SecretCert
Outputs:
AcmPcaColorTellerEndpointCertArn:
Value: !Ref AcmPcaColorTellerEndpointCert
Export:
Name: !Sub "${EnvironmentName}:AcmPcaColorTellerEndpointCertArn"
AcmPcaColorGatewayEndpointCertArn:
Value: !Ref AcmPcaColorGatewayEndpointCert
Export:
Name: !Sub "${EnvironmentName}:AcmPcaColorGatewayEndpointCertArn"
AcmPcaColorTellerRootCAArn:
Value: !Ref AcmPcaColorTellerRootCA
Export:
Name: !Sub "${EnvironmentName}:AcmPcaColorTellerRootCAArn"
AcmPcaColorGatewayRootCAArn:
Value: !Ref AcmPcaColorGatewayRootCA
Export:
Name: !Sub "${EnvironmentName}:AcmPcaColorGatewayRootCAArn"
SecretCertArn:
Value: !Ref SecretCert
Export:
Name: !Sub "${EnvironmentName}:SecretCertArn"