AWSTemplateFormatVersion: '2010-09-09' Description: Creates a code-server IDE for the EKS workshop Parameters: InstanceVolumeSize: Type: Number Description: The Size in GB of the Cloud9 Instance Volume. Default: 30 RepositoryOwner: Type: String Description: The owner of the GitHub repository to be used to bootstrap Cloud9 Default: aws-samples RepositoryName: Type: String Description: The name of the GitHub repository to be used to bootstrap Cloud9 Default: eks-workshop-v2 RepositoryRef: Type: String Description: The Git reference to be used to bootstrap Cloud9 Default: main ResourcesPrecreated: Type: String Description: Whether lab infrastructure has been pre-provisioned Default: 'false' AllowedValues: - 'false' - 'true' AnalyticsEndpoint: Type: String Description: Analytics endpoint used for AWS events Default: '' CodeServerVersion: Type: String Description: Default code-server version to use Default: 4.91.1 AmiParameterStoreName: Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64 Environment: Type: String Description: For testing purposes only Default: '' SshKeyName: Type: String Description: The name of the SSH Key Resources: VPC: Type: AWS::EC2::VPC Properties: CidrBlock: 10.0.0.0/24 EnableDnsSupport: true EnableDnsHostnames: true InternetGateway: Type: AWS::EC2::InternetGateway GatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPC InternetGatewayId: !Ref InternetGateway PublicSubnet: Type: AWS::EC2::Subnet Properties: CidrBlock: 10.0.0.0/24 VpcId: !Ref VPC MapPublicIpOnLaunch: true AvailabilityZone: !Select - 0 - !GetAZs '' PublicSubnetRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPC PublicSubnetRoute: Type: AWS::EC2::Route DependsOn: GatewayAttachment Properties: RouteTableId: !Ref PublicSubnetRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicSubnetRouteTableAssoc: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref PublicSubnetRouteTable SubnetId: !Ref PublicSubnet SecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: SG for IDE SecurityGroupIngress: - Description: Allow SSH into EC2 IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: 0.0.0.0/0 SecurityGroupEgress: - Description: Allow all outbound traffic IpProtocol: -1 CidrIp: 0.0.0.0/0 VpcId: !Ref VPC EksWorkshopIdeLambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: / Policies: - PolicyName: !Join - '' - - EksWorkshopIdeLambdaPolicy- - !Ref AWS::Region PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: arn:aws:logs:*:*:* - Effect: Allow Action: - iam:PassRole - ssm:SendCommand - ssm:GetCommandInvocation Resource: '*' EksWorkshopIdeBootstrapInstanceLambda: Type: Custom::EksWorkshopIdeBootstrapInstanceLambda DependsOn: - EksWorkshopIdeLambdaExecutionRole Properties: ServiceToken: !GetAtt EksWorkshopIdeBootstrapInstanceLambdaFunction.Arn REGION: !Ref AWS::Region InstanceId: !Ref EksWorkshopIdeInstance SsmDocument: !Ref EksWorkshopIdeSSMDocument #UpdateTrigger: # Ref: UpdateTrigger EksWorkshopIdeBootstrapInstanceLambdaFunction: Type: AWS::Lambda::Function Properties: Handler: index.lambda_handler Role: !GetAtt EksWorkshopIdeLambdaExecutionRole.Arn Runtime: python3.12 Environment: Variables: DiskSize: !Ref InstanceVolumeSize MemorySize: 256 Timeout: '900' Code: ZipFile: | from __future__ import print_function import boto3 import json import os import time import traceback import cfnresponse import logging logger = logging.getLogger(__name__) def lambda_handler(event, context): print(event.values()) print('context: {}'.format(context)) responseData = {} status = cfnresponse.SUCCESS if event['RequestType'] == 'Delete': responseData = {'Success': 'Custom Resource removed'} cfnresponse.send(event, context, status, responseData, 'CustomResourcePhysicalID') else: try: # Open AWS clients #ec2 = boto3.client('ec2') ssm = boto3.client('ssm') instance_id = event['ResourceProperties']['InstanceId'] ssm_document = event['ResourceProperties']['SsmDocument'] print('Sending SSM command...') response = ssm.send_command( InstanceIds=[instance_id], DocumentName=ssm_document) command_id = response['Command']['CommandId'] waiter = ssm.get_waiter('command_executed') waiter.wait( CommandId=command_id, InstanceId=instance_id, WaiterConfig={ 'Delay': 10, 'MaxAttempts': 60 } ) responseData = {'Success': 'Started bootstrapping for instance: '+instance_id} cfnresponse.send(event, context, status, responseData, 'CustomResourcePhysicalID') except Exception as e: status = cfnresponse.FAILED print(traceback.format_exc()) responseData = {'Error': traceback.format_exc(e)} finally: cfnresponse.send(event, context, status, responseData, 'CustomResourcePhysicalID') EksWorkshopIdeSSMDocument: Type: AWS::SSM::Document Properties: DocumentType: Command DocumentFormat: YAML Content: schemaVersion: '2.2' description: Bootstrap Cloud9 Instance mainSteps: - action: aws:runShellScript name: EksWorkshopIdebootstrap inputs: runCommand: - !Sub | set -e yum install -y git tar gzip vim nodejs npm make gcc g++ export environment="${Environment}" source <(curl -fsSL https://raw.githubusercontent.com/${RepositoryOwner}/${RepositoryName}/${RepositoryRef}/hack/lib/common-env.sh) dnf copr enable -y @caddy/caddy epel-9-x86_64 dnf install -y caddy systemctl enable --now caddy tee /etc/profile.d/custom_prompt.sh < ~/.local/share/code-server/coder.json curl -fsSL https://raw.githubusercontent.com/${RepositoryOwner}/${RepositoryName}/${RepositoryRef}/lab/scripts/setup.sh | bash code-server --install-extension ms-kubernetes-tools.vscode-kubernetes-tools --force code-server --install-extension redhat.vscode-yaml --force EOT systemctl restart code-server@ec2-user EksWorkshopIdeRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com - ssm.amazonaws.com Action: - sts:AssumeRole Policies: - PolicyName: ide-password PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - secretsmanager:GetResourcePolicy - secretsmanager:GetSecretValue - secretsmanager:DescribeSecret - secretsmanager:ListSecretVersionIds Resource: - !Ref EksWorkshopIdePassword - Effect: Allow Action: secretsmanager:ListSecrets Resource: '*' ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore Path: / EksWorkshopIamPolicy: Type: AWS::IAM::ManagedPolicy Properties: Roles: - !Ref EksWorkshopIdeRole ManagedPolicyName: !Sub ${AWS::StackName}-iam PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - iam:CreateRole - iam:GetRolePolicy - iam:DetachRolePolicy - iam:AttachRolePolicy - iam:PutRolePolicy - iam:DeleteRolePolicy - iam:DeleteRole - iam:ListInstanceProfilesForRole - iam:ListAttachedRolePolicies - iam:ListRolePolicies - iam:TagRole - iam:PassRole - sts:AssumeRole Resource: - !Sub arn:aws:iam::${AWS::AccountId}:role/eks-workshop* - !Sub arn:aws:iam::${AWS::AccountId}:role/eksctl-eks-workshop* - Effect: Allow Action: - iam:CreatePolicy - iam:DeletePolicy - iam:GetPolicyVersion - iam:ListPolicyVersions - iam:TagPolicy - iam:GetPolicy Resource: - !Sub arn:aws:iam::${AWS::AccountId}:policy/eks-workshop* - !Sub arn:aws:iam::${AWS::AccountId}:policy/eksctl-eks-workshop* - Effect: Allow Action: - iam:CreateInstanceProfile - iam:DeleteInstanceProfile - iam:GetInstanceProfile - iam:TagInstanceProfile - iam:RemoveRoleFromInstanceProfile - iam:AddRoleToInstanceProfile Resource: - !Sub arn:aws:iam::${AWS::AccountId}:instance-profile/eks-workshop* - !Sub arn:aws:iam::${AWS::AccountId}:instance-profile/eksctl-eks-workshop* - !Sub arn:aws:iam::${AWS::AccountId}:instance-profile/eks-* - Effect: Allow Action: - iam:CreateUser - iam:DeleteUser - iam:TagUser - iam:GetUser - iam:ListGroupsForUser - iam:AttachUserPolicy - iam:DetachUserPolicy - iam:ListAttachedUserPolicies - iam:*SSHPublicKey Resource: - !Sub arn:aws:iam::${AWS::AccountId}:user/eks-workshop* - Effect: Allow Action: - iam:ListOpenIDConnectProviders - iam:CreateOpenIDConnectProvider - iam:DeleteOpenIDConnectProvider - iam:TagOpenIDConnectProvider - iam:GetOpenIDConnectProvider - iam:GetRole Resource: - '*' - Effect: Allow Action: - iam:CreateServiceLinkedRole Resource: - '*' Condition: StringEquals: iam:AWSServiceName: - eks.amazonaws.com - eks-nodegroup.amazonaws.com - eks-fargate.amazonaws.com EksWorkshopBasePolicy: Type: AWS::IAM::ManagedPolicy Properties: Roles: - !Ref EksWorkshopIdeRole ManagedPolicyName: !Sub ${AWS::StackName}-base PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - eks:* - ec2:CreateLaunchTemplate - ec2:DeleteLaunchTemplate - sts:GetCallerIdentity Resource: - '*' - Effect: Allow Action: - cloudformation:CreateStack Resource: - !Sub arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/eksctl-eks-workshop* Condition: 'Null': cloudformation:RoleARN: 'true' - Effect: Allow Action: - cloudformation:DeleteStack Resource: - !Sub arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/eksctl-eks-workshop* Condition: 'Null': cloudformation:RoleARN: 'true' - Effect: Allow Action: - cloudformation:Get* - cloudformation:Describe* - cloudformation:List* - cloudformation:TagResource Resource: - '*' - Effect: Allow Action: - autoscaling:UpdateAutoScalingGroup Resource: - '*' Condition: StringLike: aws:ResourceTag/eks:cluster-name: - eks-workshop - Effect: Allow Action: - autoscaling:Get* - autoscaling:Describe* Resource: - '*' - Effect: Allow Action: - ecr-public:GetAuthorizationToken - sts:GetServiceBearerToken Resource: - '*' - Effect: Allow Action: - kms:CreateKey - kms:TagResource - kms:ScheduleKeyDeletion - kms:CreateGrant - kms:EnableKeyRotation - kms:GetKeyPolicy - kms:GetKeyRotationStatus - kms:ListResourceTags - kms:PutKeyPolicy Resource: - '*' - Effect: Allow Action: - kms:Decrypt - kms:DescribeKey - kms:EnableKeyRotation - kms:Encrypt - kms:GenerateDataKey - kms:GenerateDataKeyWithoutPlaintext Resource: - '*' Condition: StringLike: kms:RequestAlias: alias/eks-workshop* - Effect: Allow Action: - kms:CreateAlias - kms:DeleteAlias Resource: - !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:alias/eks-workshop* - !Sub arn:aws:kms:${AWS::Region}:${AWS::AccountId}:key/* - Effect: Allow Action: - kms:List* - kms:Get* - kms:Describe* Resource: - '*' EksWorkshopEc2Policy: Type: AWS::IAM::ManagedPolicy Properties: Roles: - !Ref EksWorkshopIdeRole ManagedPolicyName: !Sub ${AWS::StackName}-ec2 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ec2:Get* - ec2:Describe* - ec2:List* - ec2:RunInstances Resource: - '*' - Effect: Allow Action: - ec2:TerminateInstances Resource: - '*' Condition: StringLike: aws:ResourceTag/env: - eks-workshop* - Effect: Deny Action: ec2:RunInstances Resource: - !Sub arn:aws:ec2:*:*:instance/* Condition: ForAnyValue:StringNotLike: ec2:InstanceType: - m5.large - t4g.medium - c*.large - Effect: Allow Action: - ec2:CreateVpc - ec2:CreateSubnet - ec2:CreateRouteTable - ec2:CreateRoute - ec2:CreateInternetGateway - ec2:AttachInternetGateway - ec2:AssociateRouteTable - ec2:ModifyVpcAttribute - ec2:CreateSecurityGroup - ec2:AllocateAddress - ec2:ReleaseAddress - ec2:DisassociateAddress - ec2:CreateNetworkAclEntry - ec2:DeleteNetworkAclEntry - ec2:CreateNatGateway - ec2:DeleteNatGateway Resource: - '*' - Effect: Allow Action: - ec2:DeleteVpc - ec2:DeleteSubnet - ec2:DeleteRouteTable - ec2:DeleteRoute - ec2:DeleteInternetGateway - ec2:DetachInternetGateway - ec2:DisassociateRouteTable - ec2:ModifyVpcAttribute - ec2:ModifySubnetAttribute - ec2:AuthorizeSecurityGroup* - ec2:UpdateSecurityGroupRuleDescriptionsEgress - ec2:RevokeSecurityGroup* - ec2:DeleteSecurityGroup - ec2:ModifySecurityGroupRules - ec2:UpdateSecurityGroupRuleDescriptionsIngress Resource: - '*' Condition: StringLike: aws:ResourceTag/env: - eks-workshop* - Effect: Allow Action: - ec2:AuthorizeSecurityGroup* - ec2:RevokeSecurityGroup* Resource: - '*' Condition: StringLike: aws:ResourceTag/aws:eks:cluster-name: - eks-workshop* - Effect: Allow Action: - ec2:CreateTags - ec2:DeleteTags Resource: - '*' - Effect: Allow Action: - ec2:AssociateVpcCidrBlock - ec2:DisassociateVpcCidrBlock Resource: - !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/* Condition: StringLike: aws:ResourceTag/env: - eks-workshop* EksWorkshopLabsPolicy1: Type: AWS::IAM::ManagedPolicy DependsOn: - EksWorkshopIdeRole Properties: Roles: - !Ref EksWorkshopIdeRole ManagedPolicyName: !Sub ${AWS::StackName}-labs1 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - aps:CreateWorkspace - aps:TagResource Resource: - '*' Condition: StringLike: aws:RequestTag/env: - eks-workshop* - Effect: Allow Action: - aps:DeleteWorkspace - aps:Describe* - aps:List* - aps:QueryMetrics Resource: - '*' Condition: StringLike: aws:ResourceTag/env: - eks-workshop* - Effect: Allow Action: - dynamodb:ListTables Resource: - '*' - Effect: Allow Action: - dynamodb:CreateTable - dynamodb:DeleteTable - dynamodb:DescribeTable - dynamodb:DescribeContinuousBackups - dynamodb:ListTagsOfResource - dynamodb:DescribeTimeToLive - dynamodb:Scan - dynamodb:TagResource Resource: - !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/eks-workshop* - Effect: Allow Action: - secretsmanager:ListSecrets Resource: - '*' - Effect: Allow Action: - secretsmanager:CreateSecret - secretsmanager:DeleteSecret - secretsmanager:DescribeSecret Resource: - !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:eks-workshop* - Effect: Allow Action: - secretsmanager:ListSecrets Resource: - '*' - Effect: Allow Action: - sqs:CreateQueue - sqs:DeleteQueue - sqs:GetQueueAttributes - sqs:SetQueueAttributes - sqs:TagQueue - sqs:ListQueueTags Resource: - !Sub arn:aws:sqs:${AWS::Region}:${AWS::AccountId}:eks-workshop* - Effect: Allow Action: - rds:DescribeDBInstances Resource: - '*' - Effect: Allow Action: - rds:CreateDBInstance - rds:CreateTenantDatabase - rds:DeleteDBInstance - rds:DeleteTenantDatabase - rds:DescribeDBInstances - rds:AddTagsToResource - rds:ListTagsForResource Resource: - !Sub arn:aws:rds:${AWS::Region}:${AWS::AccountId}:db:eks-workshop* - Effect: Allow Action: - rds:CreateDBInstance - rds:CreateDBSubnetGroup - rds:DeleteDBSubnetGroup - rds:DescribeDBSubnetGroups - rds:AddTagsToResource - rds:ListTagsForResource Resource: - !Sub arn:aws:rds:${AWS::Region}:${AWS::AccountId}:subgrp:eks-workshop* - Effect: Allow Action: - lambda:AddPermission - lambda:CreateFunction - lambda:DeleteFunction - lambda:GetFunction - lambda:GetFunctionCodeSigningConfig - lambda:GetPolicy - lambda:GetRuntimeManagementConfig - lambda:ListVersionsByFunction - lambda:RemovePermission - lambda:TagResource Resource: - !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:eks-workshop* - Effect: Allow Action: - lambda:GetLayerVersion Resource: - '*' - Effect: Allow Action: - es:CreateDomain - es:DeleteDomain - es:DescribeDomain - es:DescribeDomainConfig - es:GetCompatibleVersions - es:ListTags - es:AddTags Resource: - !Sub arn:aws:es:${AWS::Region}:${AWS::AccountId}:domain/eks-workshop* - Effect: Allow Action: - elasticloadbalancing:Describe* - elasticloadbalancing:Get* Resource: - '*' - Effect: Allow Action: - cloudwatch:DeleteDashboards - cloudwatch:GetDashboard - cloudwatch:PutDashboard Resource: - !Sub arn:aws:cloudwatch::${AWS::AccountId}:dashboard/* - Effect: Allow Action: - cloudwatch:GetMetricData Resource: - '*' - Effect: Allow Action: - ecr:CreateRepository - ecr:DeleteRepository - ecr:DescribeRepositories - ecr:ListTagsForResource - ecr:TagResource Resource: - !Sub arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/retail-store-sample* - !Sub arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/eks-workshop* - Effect: Allow Action: - guardduty:CreateDetector - guardduty:DeleteDetector - guardduty:ListDetectors Resource: - '*' EksWorkshopLabsPolicy2: Type: AWS::IAM::ManagedPolicy DependsOn: - EksWorkshopIdeRole Properties: Roles: - !Ref EksWorkshopIdeRole ManagedPolicyName: !Sub ${AWS::StackName}-labs2 PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:DescribeLogGroups - logs:ListTagsForResource Resource: - '*' - Effect: Allow Action: - logs:CreateLogGroup - logs:DeleteLogGroup - logs:DeleteSubscriptionFilter - logs:PutRetentionPolicy - logs:PutSubscriptionFilter - logs:TagResource - logs:TagLogGroup - logs:Get* - logs:Describe* - logs:List* Resource: - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:eks-workshop* - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/eks-workshop* - !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/eks/eks-workshop* - Effect: Allow Action: - events:DeleteRule - events:DescribeRule - events:ListTagsForResource - events:ListTargetsByRule - events:PutRule - events:PutTargets - events:RemoveTargets - events:TagResource Resource: - !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/eks-workshop* - !Sub arn:aws:events:${AWS::Region}:${AWS::AccountId}:rule/eks-workshop* - Effect: Allow Action: - vpc-lattice:List* - vpc-lattice:Get* - vpc-lattice:DeleteServiceNetwork - vpc-lattice:DeleteServiceNetworkVpcAssociation Resource: - '*' - Effect: Allow Action: - elasticfilesystem:CreateFileSystem - elasticfilesystem:CreateMountTarget - elasticfilesystem:DeleteFileSystem - elasticfilesystem:DeleteMountTarget - elasticfilesystem:DescribeLifecycleConfiguration - elasticfilesystem:DescribeMountTargetSecurityGroups - elasticfilesystem:DescribeMountTargets - elasticfilesystem:CreateTags - elasticfilesystem:TagResource - elasticfilesystem:DescribeFileSystems Resource: - !Sub arn:aws:elasticfilesystem:${AWS::Region}:${AWS::AccountId}:file-system/* - Effect: Allow Action: - ssm:DescribeParameters - ssm:ListTagsForResource Resource: - '*' - Effect: Allow Action: - ssm:PutParameter - ssm:GetParameter - ssm:GetParameters - ssm:DeleteParameter - ssm:AddTagsToResource Resource: - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/eks-workshop* - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/eksworkshop/eks-workshop* - Effect: Allow Action: - ssm:GetParameter Resource: - !Sub arn:aws:ssm:${AWS::Region}::parameter/aws/service/eks/optimized-ami/* - Effect: Allow Action: - s3:CreateBucket - s3:DeleteBucket - s3:List* - s3:Get* - s3:PutBucketPublicAccessBlock - s3:PutBucketTagging - s3:DeleteObject - s3:DeleteObjectVersion Resource: - arn:aws:s3:::eks-workshop* - arn:aws:s3:::eks-workshop*/* - Effect: Allow Action: - codecommit:CreateRepository - codecommit:GetRepository - codecommit:DeleteRepository - codecommit:TagResource - codecommit:ListTagsForResource Resource: - !Sub arn:aws:codecommit:${AWS::Region}:${AWS::AccountId}:eks-workshop* - Effect: Allow Action: - codebuild:CreateProject - codebuild:DeleteProject - codebuild:BatchGetProjects Resource: - !Sub arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/eks-workshop* - Effect: Allow Action: - codepipeline:CreatePipeline - codepipeline:DeletePipeline - codepipeline:GetPipeline - codepipeline:GetPipelineState - codepipeline:ListTagsForResource - codepipeline:TagResource Resource: - !Sub arn:aws:codepipeline:${AWS::Region}:${AWS::AccountId}:eks-workshop* EksWorkshopIdeInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref EksWorkshopIdeRole EksWorkshopIdeInstance: Type: AWS::EC2::Instance Properties: ImageId: !Ref AmiParameterStoreName InstanceType: t3.medium KeyName: !Sub ${SshKeyName} BlockDeviceMappings: - Ebs: VolumeSize: !Ref InstanceVolumeSize VolumeType: gp3 DeleteOnTermination: true Encrypted: true DeviceName: /dev/xvda SubnetId: !Ref PublicSubnet SecurityGroupIds: - !Ref SecurityGroup IamInstanceProfile: !Ref EksWorkshopIdeInstanceProfile Tags: - Key: type Value: eksworkshop-ide EksWorkshopIdePassword: Type: AWS::SecretsManager::Secret Properties: Name: !Sub ${AWS::StackName}-password GenerateSecretString: ExcludeCharacters: '"@/\' ExcludePunctuation: true GenerateStringKey: password IncludeSpace: false PasswordLength: 32 SecretStringTemplate: '{"password":""}' UpdateReplacePolicy: Delete DeletionPolicy: Delete Outputs: IdePasswordSecret: Value: !Sub - https://console.aws.amazon.com/secretsmanager/secret?name=${SecretName} - SecretName: !Sub ${AWS::StackName}-password IdeRole: Value: !Sub ${EksWorkshopIdeRole.Arn} IdeInstancePublicIP: Value: !GetAtt EksWorkshopIdeInstance.PublicIp Export: Name: !Sub ${AWS::StackName}-code-server-public-ip IdeInstanceId: Value: !Ref EksWorkshopIdeInstance Export: Name: !Sub ${AWS::StackName}-ide-instance-id