--- AWSTemplateFormatVersion: '2010-09-09' Description: 'HashiCorp Vault, License: Apache 2.0 (Please do not remove) Oct,18,2019' Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: VPC network configuration Parameters: - AvailabilityZones - VPCCIDR - PrivateSubnet1CIDR - PrivateSubnet2CIDR - PrivateSubnet3CIDR - PublicSubnet1CIDR - PublicSubnet2CIDR - PublicSubnet3CIDR - AccessCIDR - Label: default: Bastion configuration Parameters: - NumBastionHosts - Label: default: HashiCorp Vault configuration Parameters: - KeyPairName - VaultVersion - VaultAMIOS - VaultServerNodes - VaultInstanceType - VaultNumberOfKeys - VaultNumberOfKeysForUnseal - VaultClientRoleName - VaultClientNodes - VaultKubernetesEnable - VaultKubernetesHostURL - VaultKubernetesRoleName - VaultKubernetesCertificate - VaultKubernetesJWT - VaultKubernetesServiceAccount - VaultKubernetesNameSpace - VaultKubernetesPolicies - Label: default: AWS Quick Start configuration Parameters: - QSS3BucketName - QSS3KeyPrefix - QSS3BucketRegion - Label: default: Load Balancer configuration Parameters: - LoadBalancerType - DomainName - HostedZoneID - ACMSSLCertificateArn ParameterLabels: AvailabilityZones: default: Availability Zones KeyPairName: default: EC2 key pair NumBastionHosts: default: Bastion hosts PrivateSubnet1CIDR: default: Private subnet 1 CIDR PrivateSubnet2CIDR: default: Private subnet 2 CIDR PrivateSubnet3CIDR: default: Private subnet 3 CIDR PublicSubnet1CIDR: default: Public subnet 1 CIDR PublicSubnet2CIDR: default: Public subnet 2 CIDR PublicSubnet3CIDR: default: Public subnet 3 CIDR QSS3BucketName: default: Quick Start S3 bucket name QSS3KeyPrefix: default: Quick Start S3 object key prefix QSS3BucketRegion: default: Quick Start S3 bucket Region AccessCIDR: default: Permitted IP range VPCID: default: VPC ID VPCCIDR: default: VPC CIDR VaultVersion: default: HashiCorp Vault version VaultAMIOS: default: Vault cluster operating system VaultClientNodes: default: Vault client nodes VaultServerNodes: default: Vault server nodes VaultInstanceType: default: Instance type VaultNumberOfKeys: default: Unseal keys to create VaultNumberOfKeysForUnseal: default: Required unseal keys VaultClientRoleName: default: Vault AWS role name LoadBalancerType: default: "Internal/external load balancer" ACMSSLCertificateArn: default: SSL certificate ARN HostedZoneID: default: Hosted-zone ID DomainName: default: Load balancer DNS domain name VaultKubernetesEnable: default: "Enable Kubernetes authentication" VaultKubernetesRoleName: default: Kubernetes Vault role name VaultKubernetesHostURL: default: "Kubernetes host URL" VaultKubernetesCertificate: default: "Kubernetes CA certificate" VaultKubernetesJWT: default: "Kubernetes JWT token" VaultKubernetesServiceAccount: default: "Kubernetes service account name" VaultKubernetesNameSpace: default: "Kubernetes name space" VaultKubernetesPolicies: default: "Kubernetes Vault policies" Conditions: UsingDefaultBucket: !Equals [!Ref QSS3BucketName, 'aws-quickstart'] Parameters: AvailabilityZones: Description: "List of Availability Zones to use for the VPC subnets. Three Availability Zones are used for this deployment." Type: List VaultAMIOS: AllowedValues: - Ubuntu-2004-HVM - CIS-Ubuntu-2004-HVM Default: Ubuntu-2004-HVM Description: Linux distribution AMI for the Vault instances. Type: String KeyPairName: Description: Key pair to securely connect to your instance. after it launches. Type: AWS::EC2::KeyPair::KeyName NumBastionHosts: Description: Enter the number of bastion hosts to create. AllowedValues: - 1 - 2 Type: String Default: 1 PrivateSubnet1CIDR: AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$" Default: 10.0.0.0/19 Description: CIDR block for private subnet 1 located in Availability Zone 1. Type: String PrivateSubnet2CIDR: AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$" Default: 10.0.32.0/19 Description: CIDR block for private subnet 2 located in Availability Zone 2. Type: String PrivateSubnet3CIDR: AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$" Default: 10.0.64.0/19 Description: CIDR block for private subnet 3 located in Availability Zone 3. Type: String PublicSubnet1CIDR: AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$" Default: 10.0.128.0/20 Description: CIDR block for public DMZ subnet 1 located in Availability Zone 1. 1 Type: String PublicSubnet2CIDR: AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$" Default: 10.0.144.0/20 Description: CIDR block for public DMZ subnet 2 located in Availability Zone 2. 2 Type: String PublicSubnet3CIDR: AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$" Default: 10.0.160.0/20 Description: CIDR block for public DMZ subnet 3 located in Availability Zone 3. 3 Type: String QSS3BucketName: AllowedPattern: "^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$" ConstraintDescription: Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Default: aws-quickstart Description: S3 bucket name for the Quick Start assets. The Quick Start bucket name can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). Type: String QSS3BucketRegion: Default: 'us-east-1' Description: "Region where the Quick Start S3 bucket (QSS3BucketName) is hosted. If you use your own bucket, specify the applicable Region." Type: String QSS3KeyPrefix: AllowedPattern: "^[0-9a-zA-Z-/]*$" ConstraintDescription: Quick Start key prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and a forward slash (/). Default: quickstart-hashicorp-vault/ Description: S3 key prefix for the Quick Start assets. The prefix can include numbers, lowercase letters, uppercase letters, hyphens (-), and a forward slash (/). Type: String VPCCIDR: AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$" ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 Default: 10.0.0.0/16 Description: CIDR block for the VPC. Type: String AccessCIDR: AllowedPattern: "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\\/([0-9]|[1-2][0-9]|3[0-2]))$" Description: "CIDR IP range permitted to access Vault. A value of 0.0.0.0/0 allows access from any IP address." Type: String VaultServerNodes: Type: String Description: 'Sets DesiredCapacity and MaxSize for the Vault server Auto Scaling group.' AllowedValues: - '3' - '5' - '7' Default: '3' VaultClientNodes: Type: String Description: 'Sets DesiredCapacity and MaxSize for the Vault client Auto Scaling group.' AllowedValues: - '0' - '1' Default: '0' VaultInstanceType: Type: String Description: HashiCorp Vault node instance type. AllowedValues: - 'c5.12xlarge' - 'c5.18xlarge' - 'c5.24xlarge' - 'c5.2xlarge' - 'c5.4xlarge' - 'c5.9xlarge' - 'c5.large' - 'c5.xlarge' - 'm5.12xlarge' - 'm5.16xlarge' - 'm5.24xlarge' - 'm5.2xlarge' - 'm5.4xlarge' - 'm5.8xlarge' - 'm5.large' - 'm5.metal' - 'm5.xlarge' - 'r5.12xlarge' - 'r5.16xlarge' - 'r5.24xlarge' - 'r5.2xlarge' - 'r5.4xlarge' - 'r5.8xlarge' - 'r5.large' - 'r5.xlarge' - 't3.2xlarge' - 't3.large' - 't3.medium' - 't3.micro' - 't3.nano' - 't3.small' - 't3.xlarge' ConstraintDescription: "Choose an instance type (m5.large or larger is recommended)." Default: m5.large VaultNumberOfKeys: Type: String Default: '5' AllowedPattern: "^([1-9]|[1-8][0-9]|9[0-9])$" ConstraintDescription: Must be a value in the range 1-99. Description: Number of unseal keys to create for HashiCorp Vault. VaultNumberOfKeysForUnseal: Type: String Default: '3' AllowedPattern: "^([1-9]|[1-8][0-9]|9[0-9])$" ConstraintDescription: Must be a value in the range 1-99. Description: Number of keys required to unseal HashiCorp Vault. VaultClientRoleName: Type: String Default: client-role-iam MinLength: "3" ConstraintDescription: This identifier should be at least 3 characters in length. Description: The HashiCorp Vault name for the AWS IAM Role. VaultVersion: Type: String Description: Specify which version of HashiCorp Vault to install. Default: 1.10.3 AllowedValues: - 1.5.5 - 1.6.1 - 1.10.3 LoadBalancerType: Type: String Default: "Internal" Description: Specify if the load balancer for HashiCorp Vault is internal or external. AllowedValues: - "Internal" - "External" DomainName: Type: String Description: Fully qualified domain name for the HashiCorp Vault load balancer. If you don't provide a value for ACMSSLCertificateArn, use the HostedZoneID. MaxLength: 128 Default: "" HostedZoneID: Type: String Description: Route 53-hosted zone ID of the domain name. If you don't provide an ACMSSLCertificateArn value, the Quick Start creates the ACM certificate for you using HostedZoneID in conjunction with DomainName. Default: "" ACMSSLCertificateArn: Description: Amazon Resource Name (ARN) of the load balancer's SSL certificate. If you don't provide values for DomainName and HostedZoneID, provide a value for ACMSSLCertificateArn. Type: String Default: "" VaultKubernetesEnable: Description: Enables Kubernetes authentication and creates a Kubernetes authentication role. Type: String Default: 'false' AllowedValues: - 'true' - 'false' VaultKubernetesRoleName: Description: Internal Vault name for the Kubernetes authentication role. Type: String Default: 'kube-auth-role' VaultKubernetesHostURL: Description: "URL of Kubernetes cluster (e.g., https://192.168.99.100:8443)." Type: String VaultKubernetesCertificate: Description: "AWS SSM Parameter containing a base64-encoded PEM CA certificate of the Kubernetes cluster service account." Default: "" Type: String VaultKubernetesJWT: Description: "AWS SSM Secure Parameter containing a base64-encoded JWT token of the Kubernetes cluster service account." Default: "" Type: String VaultKubernetesServiceAccount: Description: "Name of Kubernetes service account." Default: vault-auth Type: String VaultKubernetesNameSpace: Description: "Vault namespace of Kubernetes service account." Default: default Type: String VaultKubernetesPolicies: Description: Vault policies for Kubernetes service account. Default: default Type: String Resources: VPCStack: Metadata: cfn-lint: config: ignore_checks: - W9198 Properties: Parameters: AvailabilityZones: Fn::Join: - "," - Ref: AvailabilityZones KeyPairName: Ref: KeyPairName NumberOfAZs: '3' PrivateSubnet1ACIDR: Ref: PrivateSubnet1CIDR PrivateSubnet2ACIDR: Ref: PrivateSubnet2CIDR PrivateSubnet3ACIDR: Ref: PrivateSubnet3CIDR PublicSubnet1CIDR: Ref: PublicSubnet1CIDR PublicSubnet2CIDR: Ref: PublicSubnet2CIDR PublicSubnet3CIDR: Ref: PublicSubnet3CIDR VPCCIDR: Ref: VPCCIDR TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-aws-vpc/templates/aws-vpc.template' - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Type: AWS::CloudFormation::Stack LinuxBastionHostStack: Metadata: cfn-lint: config: ignore_checks: - W9198 Properties: Parameters: BastionAMIOS: Ubuntu-Server-20.04-LTS-HVM EnableTCPForwarding: 'true' KeyPairName: !Ref KeyPairName NumBastionHosts: !Ref NumBastionHosts PublicSubnet1ID: !GetAtt "VPCStack.Outputs.PublicSubnet1ID" PublicSubnet2ID: !GetAtt "VPCStack.Outputs.PublicSubnet2ID" QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Sub ${QSS3KeyPrefix}submodules/quickstart-linux-bastion/ RemoteAccessCIDR: !Ref AccessCIDR VPCID: !GetAtt "VPCStack.Outputs.VPCID" TemplateURL: !Sub - 'https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}submodules/quickstart-linux-bastion/templates/linux-bastion.template' - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Type: AWS::CloudFormation::Stack HashiCorpVaultStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub - "https://${S3Bucket}.s3.${S3Region}.${AWS::URLSuffix}/${QSS3KeyPrefix}templates/quickstart-hashicorp-vault.template" - S3Region: !If [UsingDefaultBucket, !Ref 'AWS::Region', !Ref QSS3BucketRegion] S3Bucket: !If [UsingDefaultBucket, !Sub '${QSS3BucketName}-${AWS::Region}', !Ref QSS3BucketName] Parameters: VaultAMIOS: !Ref VaultAMIOS BastionSecurityGroupID: !GetAtt "LinuxBastionHostStack.Outputs.BastionSecurityGroupID" PrivateSubnet1ID: !GetAtt "VPCStack.Outputs.PrivateSubnet1AID" PrivateSubnet2ID: !GetAtt "VPCStack.Outputs.PrivateSubnet2AID" PrivateSubnet3ID: !GetAtt "VPCStack.Outputs.PrivateSubnet3AID" PublicSubnet1ID: !GetAtt "VPCStack.Outputs.PublicSubnet1ID" PublicSubnet2ID: !GetAtt "VPCStack.Outputs.PublicSubnet2ID" PublicSubnet3ID: !GetAtt "VPCStack.Outputs.PublicSubnet3ID" QSS3BucketName: !Ref QSS3BucketName QSS3BucketRegion: !Ref QSS3BucketRegion QSS3KeyPrefix: !Ref QSS3KeyPrefix AccessCIDR: !Ref AccessCIDR VPCID: !GetAtt "VPCStack.Outputs.VPCID" VPCCIDR: !Ref VPCCIDR KeyPairName: !Ref KeyPairName VaultVersion: !Ref VaultVersion VaultInstanceType: !Ref VaultInstanceType VaultClientNodes: !Ref VaultClientNodes VaultServerNodes: !Ref VaultServerNodes VaultNumberOfKeys: !Ref VaultNumberOfKeys VaultNumberOfKeysForUnseal: !Ref VaultNumberOfKeysForUnseal VaultClientRoleName: !Ref VaultClientRoleName DomainName: !Ref DomainName HostedZoneID: !Ref HostedZoneID ACMSSLCertificateArn: !Ref ACMSSLCertificateArn LoadBalancerType: !Ref LoadBalancerType VaultKubernetesEnable: !Ref VaultKubernetesEnable VaultKubernetesRoleName: !Ref VaultKubernetesRoleName VaultKubernetesHostURL: !Ref VaultKubernetesHostURL VaultKubernetesJWT: !Ref VaultKubernetesJWT VaultKubernetesCertificate: !Ref VaultKubernetesCertificate VaultKubernetesServiceAccount: !Ref VaultKubernetesServiceAccount VaultKubernetesNameSpace: !Ref VaultKubernetesNameSpace VaultKubernetesPolicies: !Ref VaultKubernetesPolicies Outputs: BastionHost: Value: !GetAtt "LinuxBastionHostStack.Outputs.EIP1" Description: The IP Address of the Bastion host. VaultClientRoleId: Value: !Ref VaultClientRoleName Description: The HashiCorp Vault identifier of the AWS client role. VaultClientIAMRoleArn: Value: !GetAtt "HashiCorpVaultStack.Outputs.VaultClientIAMRoleArn" Description: The ARN of the AWS IAM role linked to HashiCorp Vault. VaultClientIAMRoleName: Value: !GetAtt "HashiCorpVaultStack.Outputs.VaultClientIAMRoleName" Description: The name of the AWS IAM role linked to HashiCorp Vault. VaultSecret: Value: !GetAtt "HashiCorpVaultStack.Outputs.VaultSecret" Description: The AWS Secrets Manager Secret containing the ROOT TOKEN and Recovery Secret for HashiCorp Vault. VaultKMSKeyId: Value: !GetAtt "HashiCorpVaultStack.Outputs.VaultKMSKeyId" Description: The AWS KMS Key used to Auto Unseal HashiCorp Vault and encrypt the ROOT TOKEN and Recovery Secret. VaultKMSKeyArn: Value: !GetAtt "HashiCorpVaultStack.Outputs.VaultKMSKeyArn" Description: The AWS KMS Key used to Auto Unseal HashiCorp Vault and encrypt the ROOT TOKEN and Recovery Secret. VaultLoadBalancer: Value: !GetAtt "HashiCorpVaultStack.Outputs.VaultLoadBalancer" Description: HashiCorp Vault Load Balancer address VaultAuditLogGroup: Value: !GetAtt "HashiCorpVaultStack.Outputs.VaultAuditLogGroup" Description: CloudWatch Log Group where the HashiCorp Vault audit logs are recorded Rules: DomainNamePresentWithHostedID: RuleCondition: !Equals [ !Ref HostedZoneID, '' ] Assertions: - Assert: !Not [!Equals [!Ref DomainName, '']] AssertDescription: "Please specify a 'Domain Name' if you specify 'Route 53 Hosted Zone ID'" HostedIDPresentWithDomainName: RuleCondition: !Equals [ !Ref DomainName, '' ] Assertions: - Assert: !Not [!Equals [!Ref HostedZoneID, '']] AssertDescription: "Please specify a 'Route 53 Hosted Zone ID' if you specify 'Domain Name'" GenerateOrProvideSSL: RuleCondition: !Not [!Equals [!Ref ACMSSLCertificateArn, '']] Assertions: - Assert: !And - !Equals [!Ref HostedZoneID, ''] - !Equals [!Ref DomainName, ''] AssertDescription: "Using an SSL certificate is enforced. A CertificateArn or a HostedZoneID and Domain Name must be provided." NoLoadBalancerInfoSupplied: Assertions: - Assert: !Or - !Not [!Equals [!Ref HostedZoneID, '']] - !Not [!Equals [!Ref ACMSSLCertificateArn, '']] - !Not [!Equals [!Ref DomainName, '']] AssertDescription: "Using an SSL certificate is enforced. A CertificateArn or a HostedZoneID and Domain Name must be provided."