# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 AWSTemplateFormatVersion: 2010-09-09 Resources: # Create an S3 Bucket for logs. # When deleting the stack, make sure to empty the bucket first. # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html ImageBuilderLogBucket: Type: AWS::S3::Bucket # If you want to delete the stack, but keep the bucket, set the DelectionPolicy to Retain. # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html # DeletionPolicy: Retain Properties: BucketEncryption: ServerSideEncryptionConfiguration: - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 PublicAccessBlockConfiguration: BlockPublicAcls: true IgnorePublicAcls: true BlockPublicPolicy: true RestrictPublicBuckets: true VersioningConfiguration: Status: Enabled # By default, AWS Services do not have permission to perform actions on your instances. This grants # AWS Systems Manager (SSM) and EC2 Image Builder the necessary permissions to build an image. # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html # https://docs.aws.amazon.com/imagebuilder/latest/userguide/image-builder-setting-up.html InstanceRole: Type: AWS::IAM::Role Metadata: Comment: Role to be used by instance during image build. Properties: ManagedPolicyArns: - Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore - Fn::Sub: arn:${AWS::Partition}:iam::aws:policy/EC2InstanceProfileForImageBuilder AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - !Sub 'ec2.${AWS::URLSuffix}' Version: "2012-10-17" Path: /executionServiceEC2Role/ # Policy to allow the instance to write to the S3 bucket (via instance role / instance profile). # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-policy.html InstanceRoleLoggingPolicy: Type: AWS::IAM::Policy Metadata: Comment: Allows the instance to save log files to an S3 bucket. Properties: PolicyName: ImageBuilderLogBucketPolicy Roles: - Ref: InstanceRole PolicyDocument: Version: 2012-10-17 Statement: - Action: - s3:PutObject Effect: Allow Resource: - Fn::Sub: - arn:${AWS::Partition}:s3:::${BUCKET}/* - BUCKET: Ref: ImageBuilderLogBucket # To pass the InstanceRole to an EC2 instance, we need an InstanceProfile. # This profile will be used during the image build process. # https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html InstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: /executionServiceEC2Role/ Roles: - Ref: InstanceRole # Specifies the infrastructure within which to build and test your image. # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html WindowsServer2016ImageInfrastructureConfiguration: Type: AWS::ImageBuilder::InfrastructureConfiguration Properties: Name: WindowsServer-2016-VSCode-Image-Infrastructure-Configuration InstanceProfileName: Ref: InstanceProfile # Specify an S3 bucket and EC2 Image Builder will save logs to the bucket. Logging: S3Logs: S3BucketName: Ref: ImageBuilderLogBucket # S3KeyPrefix: 'my-imagebuilder-bucket-prefix' # If you would like to keep the instance running after a failed build, set TerminateInstanceOnFailure to false. # TerminateInstanceOnFailure: false # If you do not have a default VPC or want to use a different VPC, you must specify the subnet ID to use # SubnetId: 'subnet-id' # Create a custom EC2 Image Builder component that downloads and installs Visual Studio Code. The component includes a # validation step which will run after the install but before the image capture. Also included, is a test step which # runs after the image is captured (EC2 Image Builder launches a new instance from the image and runs the test phase). # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-component.html VisualStudioCodeComponent: Type: AWS::ImageBuilder::Component Properties: Name: VisualStudioCode Version: 0.0.1 Description: Install Visual Studio Code ChangeDescription: First version Platform: Windows Data: | name: InstallVSCode description: Downloads and Installs Visual Studio Code schemaVersion: 1.0 phases: - name: build steps: - name: VSCodeInstall action: ExecutePowerShell inputs: commands: - | # Set TLS 1.2 for Invoke-RestMethod [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 # Set the download link to Visual Studio Code (64-bit installer) $downloadUrl = "https://go.microsoft.com/fwlink/?Linkid=852157" # Set the path for our download, which will be in the temp directory $installerFile = "vscode-install.exe" $installerDownloadPath = (Join-Path $env:TEMP $installerFile) # Set Install Options # Include the context menu, file association, and add to path options (and don't run code after install: $installerArguments = '/verysilent /mergetasks=!runcode,addcontextmenufiles,addcontextmenufolders,associatewithfiles,addtopath' # Download the file Invoke-Webrequest $downloadUrl -UseBasicParsing -OutFile $installerDownloadPath # Install Start-Process $installerDownloadPath -ArgumentList $installerArguments -Wait # Cleanup Remove-Item $installerDownloadPath -Force - name: validate steps: - name: VSCodeValidate action: ExecutePowerShell inputs: commands: - | $installed = Test-Path (Join-Path $env:ProgramFiles "Microsoft VS Code\Code.exe") if (-not $installed) { exit 1 } - name: test steps: - name: VSCodeTest action: ExecutePowerShell inputs: commands: - | try { code --version } catch { exit 1 } # Recipe which references the latest (x.x.x) version of Windows Server 2016 English AMI with Desktop Experience). # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html WindowsServer2016ImageRecipe: Type: AWS::ImageBuilder::ImageRecipe Properties: Name: Windows_Server-2016-VisualStudioCode Version: 0.0.1 # ${AWS::Partition} returns the partition where you are running the CloudFormation template. For standard AWS regions, the # partition is aws. For resources elsewhere, the partition is aws-partitionname. For example, China (Beijing and Ningxia) # regions use aws-cn and AWS GovCloud (US) regions are aws-us-gov. # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html ParentImage: Fn::Sub: arn:${AWS::Partition}:imagebuilder:${AWS::Region}:aws:image/windows-server-2016-english-full-base-x86/x.x.x Components: - ComponentArn: Ref: VisualStudioCodeComponent # The Image resource will show complete in CloudFormation once your image is done building. Use this resource later in your # stack to reference the image within other resources. # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-image.html WindowServer2016WithVisualStudioCode: Type: AWS::ImageBuilder::Image Properties: ImageRecipeArn: Ref: WindowsServer2016ImageRecipe InfrastructureConfigurationArn: Ref: WindowsServer2016ImageInfrastructureConfiguration # Create an SSM Parameter Store entry with our resulting ImageId. # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html WindowServer2016WithVisualStudioCodeParameter: Type: AWS::SSM::Parameter Properties: Description: Image Id for Window Server 2016 With Visual Studio Code Name: /Test/Images/Windows_Server-2016-VisualStudioCode Type: String Value: Fn::GetAtt: [WindowServer2016WithVisualStudioCode, ImageId]