# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 AWSTemplateFormatVersion: 2010-09-09 Description: "(%%SOLUTION_ID%%-targetaccount) - The AWS CloudFormation template for deployment of the AWS Cloud Migration Factory Solution (Version %%VERSION%%)" Metadata: 'AWS::CloudFormation::Interface': ParameterGroups: - Label: default: AWS CMF Deployment Account Details Parameters: - FactoryAWSAccountId - Label: default: AWS CMF Features to enable in this account Parameters: - Replatform - RehostMGN ParameterLabels: FactoryAWSAccountId: default: AWS CMF AWS Account Id Replatform: default: Allow AWS CMF access to EC2 Replatform (Cross Account) RehostMGN: default: Allow AWS CMF access to AWS MGN Rehost (Cross Account) Parameters: FactoryAWSAccountId: Type: String Description: AWS Cloud Migration Factory AWS Account Id, please replace with the correct target AWS Account Id Default: '111122223333' AllowedPattern: "[0-9]*" ConstraintDescription: AWS Account Id must be numbers Replatform: Type: String Description: Deploy Replatform EC2 Target Account Role? Default: true AllowedValues: [true, false] RehostMGN: Type: String Description: "Allow the AWS CMF account access to perform AWS MGN Rehost automation in this account? This will create the required IAM Roles that will be assumed by the AWS account specified. WARNING: Disabling this option after initial deployment will result in installed AWS MGN agents stopping working due to IAMuser being deleted." Default: true AllowedValues: [ true, false ] Conditions: DeployReplatformEC2Role: !Equals [!Ref Replatform, true] DeployRehostMGNRole: !Equals [!Ref RehostMGN, true] Resources: MGNAgentInstallUser: Condition: DeployRehostMGNRole Type: AWS::IAM::User Properties: UserName: !Sub "MGNAgentInstallUser-${AWS::AccountId}" Policies: - PolicyName: LambdaRolePolicy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - 'mgn:SendAgentMetricsForMgn' - 'mgn:SendAgentLogsForMgn' - 'mgn:SendClientLogsForMgn' Resource: '*' - Effect: Allow Action: - 'mgn:RegisterAgentForMgn' - 'mgn:UpdateAgentSourcePropertiesForMgn' - 'mgn:UpdateAgentReplicationInfoForMgn' - 'mgn:UpdateAgentConversionInfoForMgn' - 'mgn:GetAgentInstallationAssetsForMgn' - 'mgn:GetAgentCommandForMgn' - 'mgn:GetAgentConfirmedResumeInfoForMgn' - 'mgn:GetAgentRuntimeConfigurationForMgn' - 'mgn:UpdateAgentBacklogForMgn' - 'mgn:GetAgentReplicationInfoForMgn' Resource: '*' - Effect: Allow Action: 'mgn:TagResource' Resource: 'arn:aws:mgn:*:*:source-server/*' Metadata: cfn_nag: rules_to_suppress: - id: F2000 reason: "user is for agent install only, does not need to be assigned to a group" - id: F10 reason: "user is for agent install only, does not need to be assigned to a group" - id: W11 reason: "The resources ARN is unknown, because it is based on user's input" CMFMGNAutomationRole: Condition: DeployRehostMGNRole Type: 'AWS::IAM::Role' Properties: RoleName: 'CMF-MGNAutomation' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: AWS: - !Ref FactoryAWSAccountId Action: - 'sts:AssumeRole' Path: / Policies: - PolicyName: MGNSSMAccessPolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'ssm:GetAutomationExecution' - 'ssm:StartAutomationExecution' - 'ssm:DescribeDocument' Resource: - 'arn:aws:ssm:*:*:document/*' - 'arn:aws:ssm:*:*:automation-definition/*:*' - 'arn:aws:ssm:*:*:automation-execution/*' - Effect: Allow Action: - 'ssm:DescribeInstanceInformation' Resource: '*' - PolicyName: LambdaRolePolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'iam:PassRole' - 'sts:AssumeRole' Resource: "*" - Effect: Allow Action: - 'mgn:ChangeServerLifeCycleState' - 'mgn:CreateReplicationConfigurationTemplate' - 'mgn:DeleteJob' - 'mgn:DeleteReplicationConfigurationTemplate' - 'mgn:DeleteSourceServer' - 'mgn:Describe*' - 'mgn:DisconnectFromService*' - 'mgn:FinalizeCutover' - 'mgn:Get*' - 'mgn:InitializeService' - 'mgn:ListTagsForResource' - 'mgn:MarkAsArchived' - 'mgn:Notify*' - 'mgn:RegisterAgentForMgn' - 'mgn:RetryDataReplication' - 'mgn:Send*' - 'mgn:StartCutover' - 'mgn:StartTest' - 'mgn:TagResource' - 'mgn:TerminateTargetInstances' - 'mgn:UntagResource' - 'mgn:Update*' - 'mgn:Batch*' Resource: '*' - Effect: Allow Action: - 'kms:Encrypt' - 'kms:Decrypt' - 'kms:ReEncrypt*' - 'kms:GenerateDataKey*' - 'kms:CreateGrant' - 'kms:ListAliases' - 'kms:DescribeKey' Resource: '*' - Effect: Allow Action: - 'iam:GetInstanceProfile' - 'ec2:DescribeAccountAttributes' - 'ec2:DescribeAvailabilityZones' - 'ec2:DescribeImages' - 'ec2:DescribeInstances' - 'ec2:DescribeInstanceTypes' - 'ec2:DescribeInstanceAttribute' - 'ec2:DescribeInstanceStatus' - 'ec2:DescribeInstanceTypeOfferings' - 'ec2:DescribeLaunchTemplateVersions' - 'ec2:DescribeLaunchTemplates' - 'ec2:DescribeSecurityGroups' - 'ec2:DescribeSnapshots' - 'ec2:DescribeSubnets' - 'ec2:DescribeVolumes' - 'ec2:GetEbsEncryptionByDefault' - 'ec2:GetEbsDefaultKmsKeyId' - 'ec2:DescribeHosts' - 'ec2:DescribeNetworkInterfaces' - 'iam:GetInstanceProfile' Resource: '*' - Effect: Allow Action: 'iam:PassRole' Resource: - >- arn:aws:iam::*:role/service-role/AWSApplicationMigrationConversionServerRole Condition: StringEquals: 'iam:PassedToService': ec2.amazonaws.com - Effect: Allow Action: - 'ec2:DeleteSnapshot' Resource: 'arn:aws:ec2:*:*:snapshot/*' Condition: 'Null': 'aws:ResourceTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:CreateLaunchTemplateVersion' - 'ec2:ModifyLaunchTemplate' - 'ec2:DeleteLaunchTemplateVersions' Resource: 'arn:aws:ec2:*:*:launch-template/*' Condition: 'Null': 'aws:ResourceTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:DeleteVolume' Resource: 'arn:aws:ec2:*:*:volume/*' Condition: 'Null': 'aws:ResourceTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:StartInstances' - 'ec2:StopInstances' - 'ec2:TerminateInstances' - 'ec2:ModifyInstanceAttribute' - 'ec2:GetConsoleOutput' - 'ec2:GetConsoleScreenshot' Resource: 'arn:aws:ec2:*:*:instance/*' Condition: 'Null': 'aws:ResourceTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:RevokeSecurityGroupEgress' - 'ec2:AuthorizeSecurityGroupIngress' - 'ec2:AuthorizeSecurityGroupEgress' Resource: 'arn:aws:ec2:*:*:security-group/*' Condition: 'Null': 'aws:ResourceTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:CreateVolume' Resource: 'arn:aws:ec2:*:*:volume/*' Condition: 'Null': 'aws:RequestTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: 'ec2:CreateSecurityGroup' Resource: 'arn:aws:ec2:*:*:vpc/*' - Effect: Allow Action: - 'ec2:CreateSecurityGroup' Resource: 'arn:aws:ec2:*:*:security-group/*' Condition: 'Null': 'aws:RequestTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:CreateSnapshot' Resource: 'arn:aws:ec2:*:*:volume/*' Condition: 'Null': 'ec2:ResourceTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:CreateSnapshot' Resource: 'arn:aws:ec2:*:*:snapshot/*' Condition: 'Null': 'aws:RequestTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:DetachVolume' - 'ec2:AttachVolume' Resource: 'arn:aws:ec2:*:*:instance/*' Condition: 'Null': 'ec2:ResourceTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:AttachVolume' Resource: 'arn:aws:ec2:*:*:volume/*' Condition: 'Null': 'ec2:ResourceTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:DetachVolume' Resource: 'arn:aws:ec2:*:*:volume/*' - Effect: Allow Action: - 'ec2:RunInstances' Resource: 'arn:aws:ec2:*:*:instance/*' Condition: 'Null': 'aws:RequestTag/AWSApplicationMigrationServiceManaged': 'false' - Effect: Allow Action: - 'ec2:RunInstances' Resource: - 'arn:aws:ec2:*:*:security-group/*' - 'arn:aws:ec2:*:*:volume/*' - 'arn:aws:ec2:*:*:subnet/*' - 'arn:aws:ec2:*:*:image/*' - 'arn:aws:ec2:*:*:network-interface/*' - 'arn:aws:ec2:*:*:launch-template/*' - Effect: Allow Action: 'ec2:CreateTags' Resource: - 'arn:aws:ec2:*:*:security-group/*' - 'arn:aws:ec2:*:*:volume/*' - 'arn:aws:ec2:*:*:snapshot/*' - 'arn:aws:ec2:*:*:instance/*' Condition: StringEquals: 'ec2:CreateAction': - CreateSecurityGroup - CreateVolume - CreateSnapshot - RunInstances Metadata: cfn_nag: rules_to_suppress: - id: W11 reason: "The resources ARN is unknown, because it is based on user's input" - id: F38 reason: "The resources ARN is unknown, because it is based on user's input" - id: W28 reason: "Replacement of this resource is not required, and explicit name of this resource is easy for user to identify the table" - id: W76 reason: "The policy is required for managing target EC2 instances" CMFAutomationServerRole: Condition: DeployRehostMGNRole Type: 'AWS::IAM::Role' Properties: RoleName: 'CMF-AutomationServer' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: AWS: - !Ref FactoryAWSAccountId Action: - 'sts:AssumeRole' Path: / ManagedPolicyArns: - "arn:aws:iam::aws:policy/AWSApplicationMigrationAgentInstallationPolicy" Policies: - PolicyName: LambdaRolePolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'secretsmanager:DescribeSecret' - 'secretsmanager:GetSecretValue' Resource: !Sub 'arn:aws:secretsmanager:*:${AWS::AccountId}:secret:*' - Effect: Allow Action: - 'secretsmanager:ListSecrets' Resource: '*' - Effect: Allow Action: - 'mgn:DescribeJobLogItems' - 'mgn:DescribeJobs' - 'mgn:DescribeSourceServers' - 'mgn:DescribeReplicationConfigurationTemplates' - 'mgn:GetLaunchConfiguration' - 'mgn:GetReplicationConfiguration' Resource: '*' - Effect: Allow Action: - 'ec2:DescribeInstances' - 'ec2:DescribeLaunchTemplateVersions' - 'ec2:DescribeSecurityGroups' - 'ec2:DescribeSubnets' Resource: '*' - Effect: Allow Action: - 'ec2:GetConsoleScreenshot' - 'ec2:GetConsoleOutput' - 'ec2:DescribeInstanceAttribute' - 'ec2:ModifyInstanceAttribute' Resource: 'arn:aws:ec2:*:*:instance/*' Metadata: cfn_nag: rules_to_suppress: - id: W11 reason: "ListSecrets does not support resource-level permissions" - id: W28 reason: "Replacement of this resource is not required, and explicit name of this resource is easy for user to identify the table" FactoryReplatformEC2DeployRole: Condition: DeployReplatformEC2Role Type: 'AWS::IAM::Role' Properties: RoleName: 'Factory-Replatform-EC2Deploy' AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: AWS: - !Ref FactoryAWSAccountId Action: - 'sts:AssumeRole' Path: / Policies: - PolicyName: ReplatformRolePolicy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'iam:PassRole' - 'sts:AssumeRole' Resource: "*" - Effect: Allow Action: - 'cloudformation:DescribeStacks' - 'cloudformation:CreateStack' - 'cloudformation:UpdateStack' Resource: "*" - Effect: Allow Action: - 's3:GetObject' Resource: - 'arn:aws:s3:::migration-factory-*-*-gfbuild-cftemplates' - 'arn:aws:s3:::migration-factory-*-*-gfbuild-cftemplates/*' - Effect: Allow Action: - 'kms:ListAliases' - 'kms:DescribeKey' Resource: '*' - Effect: Allow Action: - 'iam:GetInstanceProfile' - 'ec2:DescribeAccountAttributes' - 'ec2:DescribeAvailabilityZones' - 'ec2:DescribeImages' - 'ec2:DescribeInstances' - 'ec2:DescribeInstanceTypes' - 'ec2:DescribeInstanceAttribute' - 'ec2:DescribeInstanceStatus' - 'ec2:DescribeInstanceTypeOfferings' - 'ec2:DescribeLaunchTemplateVersions' - 'ec2:DescribeLaunchTemplates' - 'ec2:DescribeSecurityGroups' - 'ec2:DescribeSnapshots' - 'ec2:DescribeSubnets' - 'ec2:DescribeVolumes' - 'ec2:GetEbsEncryptionByDefault' - 'ec2:GetEbsDefaultKmsKeyId' Resource: '*' - Effect: Allow Action: - 'ec2:CreateVolume' - 'ec2:DeleteVolume' - 'ec2:DetachVolume' - 'ec2:AttachVolume' - 'ec2:ModifyVolumeAttribute' Resource: 'arn:aws:ec2:*:*:volume/*' - Effect: Allow Action: - 'ec2:RunInstances' - 'ec2:StartInstances' - 'ec2:StopInstances' - 'ec2:TerminateInstances' - 'ec2:ModifyInstanceAttribute' - 'ec2:DetachVolume' - 'ec2:AttachVolume' Resource: 'arn:aws:ec2:*:*:instance/*' - Effect: Allow Action: - 'ec2:RevokeSecurityGroupEgress' - 'ec2:AuthorizeSecurityGroupIngress' - 'ec2:AuthorizeSecurityGroupEgress' Resource: 'arn:aws:ec2:*:*:security-group/*' - Effect: Allow Action: 'ec2:CreateSecurityGroup' Resource: 'arn:aws:ec2:*:*:vpc/*' - Effect: Allow Action: - 'ec2:CreateSecurityGroup' Resource: 'arn:aws:ec2:*:*:security-group/*' - Effect: Allow Action: - 'ec2:RunInstances' Resource: - 'arn:aws:ec2:*:*:security-group/*' - 'arn:aws:ec2:*:*:volume/*' - 'arn:aws:ec2:*:*:subnet/*' - 'arn:aws:ec2:*:*:image/*' - 'arn:aws:ec2:*:*:network-interface/*' - 'arn:aws:ec2:*:*:launch-template/*' - 'arn:aws:ec2:*:*:instance/*' - Effect: Allow Action: 'ec2:CreateTags' Resource: - 'arn:aws:ec2:*:*:security-group/*' - 'arn:aws:ec2:*:*:volume/*' - 'arn:aws:ec2:*:*:snapshot/*' - 'arn:aws:ec2:*:*:instance/*' Condition: StringEquals: 'ec2:CreateAction': - CreateSecurityGroup - CreateVolume - CreateSnapshot - RunInstances Metadata: cfn_nag: rules_to_suppress: - id: W11 reason: "The resources ARN is unknown, because it is based on user's input" - id: F38 reason: "The resources ARN is unknown, because it is based on user's input" - id: W28 reason: "Replacement of this resource is not required, and explicit name of this resource is easy for user to identify the table" - id: W76 reason: "The policy is required for managing target EC2 instances" MGNAccessKeyId: Condition: DeployRehostMGNRole Type: 'AWS::IAM::AccessKey' Properties: UserName: !Ref MGNAgentInstallUser MGNUserSecrets: Condition: DeployRehostMGNRole Type: AWS::SecretsManager::Secret Properties: Description: String Name: MGNAgentInstallUser SecretString: !Sub '{"AccessKeyId":"${MGNAccessKeyId}", "SecretAccessKey":"${MGNAccessKeyId.SecretAccessKey}"}' Metadata: cfn_nag: rules_to_suppress: - id: W77 reason: "cross-account sharing KMS key is not required"