CloudFormation template - http 403 error when trying to download resources from s3

0

Hi all, I'm getting to grips with CF templates and the below template is one I've created to deploy a Windows Server instance then download and run a couple of powershell scripts from an S3 bucket, these deploy ADDS to make the server a domain controller.

This template deploys the server but does not pull the files from the bucket in S3, it always throws a http 403 error.

Any thoughts based on the template?

Cheers!


AWSTemplateFormatVersion: 2010-09-09
Description: CloudFormation Template to deploy an EC2 instance and then install ADDS
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  Hostname:
    Type: String
    Description: Hostname - maximum 15 characters
    MaxLength: '15'
    Default: ad
  InstanceName:
    Description: Name of instance in AWS. Replace CUSTOMERNAME with your actual customer
      domain name.
    Type: String
    Default: ad-CUSTOMERNAME-test-local
  InstanceAMIId:
    Description: The AMI ID from which this instance will be deployed. Search Windows_Server-2016-English-Full-Base-
      in the AMI menu
    Type: AWS::EC2::Image::Id
  DomainDNSName:
    Type: String
    Description: Fully Qualified Domain Name - replace CUSTOMERNAME here
    Default: CUSTOMERNAME.test.local
  DomainNetBiosName:
    Type: String
    Description: NETBIOS Domain Name - replace CUSTOMERNAME here
    Default: CUSTOMERNAME
  DomainMode:
    Type: String
    Description: Domain Mode, use 7 for Windows Server 2016
    Default: 7
  ForestMode:
    Type: String
    Description: Domain Mode, use 7 for Windows Server 2016
    Default: 7
  SafeModeAdministratorPassword:
    MinLength: '8'
    NoEcho: 'true'
    Type: String
    Description: SafeModeAdministrator Password - used when creating ADDS
  CAName:
    Description: the name of the Certificate Authority server. Replace CUSTOMERNAME
      here.
    Type: String
    Default: CUSTOMERNAMEtestCA
  SubnetId:
    Description: Use Service Internal 1
    Type: AWS::EC2::Subnet::Id
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  RoleSecurityGroup:
    Description: The ID of the Security Group defining access to this instance based
      on it's defined role.
    Type: AWS::EC2::SecurityGroup::Id
    ConstraintDescription: This must be the ID of an existing Security Group composed
      to support this role.
  AccessSecurityGroup:
    Description: The IDs of the Security Group defining access from this instance
      into other groups.
    Type: AWS::EC2::SecurityGroup::Id
    ConstraintDescription: This must be the ID of an existing Security Group composed to support required access.
  InstanceType:
    Description: Amazon EC2 instance type
    Type: String
    Default: t3.medium
    AllowedValues:
    - t2.micro
    - t2.small
    - t2.medium
    - t2.large
    - m4.large
    - m4.xlarge
    - m4.2xlarge
    - t3.medium
    - t3.large
    - t3.xlarge
    - r5.xlarge
    - r5a.xlarge
    ConstraintDescription: must be a valid EC2 instance type.
  AvailabilityZone:
    Type: String
    Description: Default AZ. 
  IAMRole:
    Description: This is the IAM Role that will enable required access for the deployment of this instance
    Type: String
    Default: CFInstanceBasePermissionsRole
  BootVolumeSize:
    Description: This is the size (in GB) of the boot volume from which this instance will operate.
    Type: String
    Default: '80'
  EnableTerminationProtection:
    Description: The setting that determines whether delete/termination protection
      is enabled for the instance.
    Type: String
    Default: 'True'
    ConstraintDescription: This can only be True or False.
  S3BucketName:
    Default: general-application-setup
    Description: S3 bucket for boot artefacts
    Type: String
Resources:
  Profile:
    Type: 'AWS::IAM::InstanceProfile'
    Properties:
      Roles:
        - !Ref HostRole
      Path: /
      InstanceProfileName: !Join
        - ''
        - - 'instance-profile-'
          - !Ref S3BucketName
  HostRole:
    Type: 'AWS::IAM::Role'
    Properties:
      RoleName: !Join
        - ''
        - - 'role-s3-read-'
          - !Ref S3BucketName
      Policies:
        - PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Action:
                  - 's3:GetObject'
                Effect: Allow
                Resource: !Join
                  - ''
                  - - 'arn:aws:s3:::'
                    - !Ref S3BucketName
                    - '/*'
          PolicyName: s3-policy-read
      Path: /
      AssumeRolePolicyDocument:
        Statement:
          - Action:
              - 'sts:AssumeRole'
            Principal:
              Service:
                - ec2.amazonaws.com
            Effect: Allow
        Version: 2012-10-17    
  Instance:
    Type: 'AWS::EC2::Instance'
    Metadata:
      'AWS::CloudFormation::Authentication':
        S3AccessCreds:
          type: S3
          buckets:
            - !Ref S3BucketName
          roleName: !Ref HostRole
      'AWS::CloudFormation::Init':
        configSets: 
          config:
            - get-files 
            - configure-instance
        get-files:
          files:
            'c:\generalFiles\npp.8.5.3.Installer.x64.exe':
              source: https://general-application-setup.s3.us-west-1.amazonaws.com/test-tools/npp.8.5.3.Installer.x64.exe
              authentication: S3AccessCreds
            'c:\generalFiles\Add-WindowsComponents.ps1':
              source: https://general-application-setup.s3.us-west-1.amazonaws.com/test-tools/scripts/Add-WindowsComponents.ps1
              authentication: S3AccessCreds
            'c:\generalFiles\Configure-ADForest.ps1':
              source: https://general-application-setup.s3.us-west-1.amazonaws.com/test-tools/scripts/Configure-ADForest.ps1
              authentication: S3AccessCreds
        configure-instance:
          commands:
            1-set-powershell-execution-policy:
              command: >-
                powershell.exe -Command "Set-ExecutionPolicy UnRestricted -Force"
              waitAfterCompletion: '0'
            2-rename-computer:
              command: !Join
                - ''
                - - >-
                  -  powershell.exe -Command "Rename-Computer -Restart -NewName "
                  -  !Ref Hostname
              waitAfterCompletion: forever  
            3-install-windows-components:
              command: >-
                powershell.exe -Command "c:\generalFiles\Add-WindowsComponents.ps1"
              waitAfterCompletion: '0'
            4-install-ADForest:
              command: !Join
                - ''
                - - >-
                  - powershell.exe -Command "c:\generalFiles\Configure-ADForest.ps1 -DomainName '
                  - !Ref DomainDNSName
                  - ''' -DomainNetBiosName '''
                  - !Ref DomainNetBiosName
                  - ''' -DomainMode '''
                  - !Ref DomainMode
                  - ''' -ForestMode '''
                  - !Ref ForestMode 
                  - ''' -SafeModeAdministratorPassword ''' 
                  - !Ref SafeModeAdministratorPassword
                  - '''"'
              waitAfterCompletion: forever
    Properties:
      DisableApiTermination: 'false'
      AvailabilityZone: !Sub "${AvailabilityZone}"
      DisableApiTermination: !Ref EnableTerminationProtection
      IamInstanceProfile: !Ref Profile
      InstanceType: !Ref InstanceType
      ImageId: !Ref InstanceAMIId
      SecurityGroupIds: 
        - Ref: RoleSecurityGroup
        - Ref: AccessSecurityGroup
      SubnetId: !Ref SubnetId
      KeyName: !Ref KeyName
      Tags:
      - Key: Name
        Value:
          Ref: InstanceName
      BlockDeviceMappings:
        - DeviceName: "/dev/sda1"
          Ebs:
            VolumeSize: !Ref BootVolumeSize
            VolumeType: gp2                 
      KeyName: !Ref KeyName
      UserData: !Base64
        'Fn::Join': 
          - ''
          - - "<powershell>\n"
            - "cfn-init.exe "
            - " --stack "
            - "Ref": "AWS::StackId"
            - " --resource Instance"
            - " --region "
            - "Ref": "AWS::Region"
            - " --configsets config"
            - " -v \n"
            - "cfn-signal.exe  "
            - " ---exit-code 0"
            - " --region "
            - "Ref": "AWS::Region"
            - " --resource Instance" 
            - " --stack "
            - "Ref": "AWS::StackName"
            - "\n"           
            - "</powershell>\n"

Outputs:
    InstanceId:
      Description: 'InstanceId'
      Value: !Ref Instance
     
    InstancePrivateIP:
      Description: 'InstancePrivateIP'
      Value: !GetAtt Instance.PrivateIp
asked 10 months ago313 views
1 Answer
0

CloudFormation role (if you use that) should have s3 permissions:

s3:GetObject, s3:PutObject, s3:ListBucket

Also S3 bucket itself should allow CloudFormation stack access the bucket.

profile picture
answered 10 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions

Relevant content