{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": " This cloudformation template creates IAM roles, SNS topic, an S3 bucket for setting up private image build.(fdp-2n82smtoh). MIT No Attribution. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so.THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
    "Parameters": { 
  
  "EmailID": {
      "Type": "String",
      "Default": "myemail@mycompany.com",
      "AllowedPattern": "([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)",
      "Description": "Your email ID for receiving Private image build notifications."

    },
     "BucketName": {
      "Type": "String", 
      "AllowedPattern": "[a-zA-Z0-9]*image-build[a-zA-Z0-9]*",
      "Description": "Name of the bucket to be created for storing Private image build logs. Note, bucket-name must contain image-build in it."

    }
    },
    "Resources": {
       "PrivateImageBuildConfigBucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                 "BucketName": {
                    "Ref": "BucketName"
                },
                "VersioningConfiguration": {
                    "Status": "Enabled"
                },
                "BucketEncryption":
                {
                  "ServerSideEncryptionConfiguration" : [{
                  "ServerSideEncryptionByDefault" : {"SSEAlgorithm":"AES256"}
              }]
              }

            }
        },
        "PrivateImageBuildConfigBucketPolicy": {
            "Type": "AWS::S3::BucketPolicy",
            "DependsOn": "ManagedInstanceRole",
            "Properties": {
                "Bucket": {
                    "Ref": "PrivateImageBuildConfigBucket"
                },
                "PolicyDocument": {
                    "Statement": [
                        {
                            "Action": [
                                "s3:*"
                            ],
                            "Effect": "Allow",
                            "Resource": [
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "PrivateImageBuildConfigBucket"
                                            },
                                            "/*"
                                        ]
                                    ]
                                },
                                {
                                    "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "PrivateImageBuildConfigBucket"
                                            }
                                        ]
                                    ]
                                }
                            ],
                            "Principal": {
                                "AWS": [
                                    {
                                        "Fn::GetAtt": [
                                            "ManagedInstanceRole",
                                            "Arn"
                                        ]
                                    },
                                    {
                                        "Fn::GetAtt": [
                                            "AutomationServiceRole",
                                            "Arn"
                                        ]
                                    } 
                                ]
                            }
                        }
                    ]
                }
            }
        },
        "ManagedInstanceRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "ssm.amazonaws.com",
                                    "ec2.amazonaws.com"
                                ]
                            },

                            "Action": "sts:AssumeRole"
                        }
                    ]
                }, 
                "Path": "/",
                "Policies": [
                    {
                        "PolicyName": "SamplePolicy",
                        "PolicyDocument": {
                            "Version": "2012-10-17",
                            "Statement":[ { 
                           "Action": [
                           "ssm:DescribeAssociation",
                           "ssm:GetDocument",
                           "ssm:GetManifest",
                           "ssm:GetParameters",
                           "ssm:ListAssociations",
                           "ssm:ListInstanceAssociations",
                           "ssm:PutConfigurePackageResult",
                           "ssm:UpdateAssociationStatus",
                           "ssm:UpdateInstanceAssociationStatus",
                           "ssm:UpdateInstanceInformation"
                           ],
                           "Resource": "*",
                           "Effect": "Allow"
                           },
                           {
                           "Action": [
                           "ec2messages:AcknowledgeMessage",
                           "ec2messages:DeleteMessage",
                           "ec2messages:FailMessage",
                           "ec2messages:GetEndpoint",
                           "ec2messages:GetMessages",
                           "ec2messages:SendReply"
                           ],
                           "Resource": "*",
                           "Effect": "Allow"
                          },
                          {
                           "Action": [
                           "ec2:DescribeInstanceStatus"
                           ],
                           "Resource": "*",
                           "Effect": "Allow"
                          },
                          {
                           "Action": [
                              "s3:GetObject",
                              "s3:PutObject"
                           ],
                           "Resource": {  "Fn::Join": [
                                        "",
                                        [
                                            "arn:aws:s3:::",
                                            {
                                                "Ref": "PrivateImageBuildConfigBucket"
                                            },
                                            "/*"
                                        ]
                                    ]},
                           "Effect": "Allow"
                          }]
                            }
                        }
                    
                ]
            }
        },
        "ManagedInstanceProfile": {
            "Type": "AWS::IAM::InstanceProfile",
            "Properties": {
                "Path": "/",
                "Roles": [
                    {
                        "Ref": "ManagedInstanceRole"
                    }
                ]
            }
        },

          "TriggerPIBRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {     
              "ManagedPolicyArns": [
                    "arn:aws:iam::aws:policy/AWSMarketplaceImageBuildFullAccess",  
                    "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM"   
                ],
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "ssm.amazonaws.com",
                                    "ec2.amazonaws.com"
                                ]
                            },

                            "Action": "sts:AssumeRole"
                        }
                    ]
                }
            }
        },
        "TriggerImageProfile": {
            "Type": "AWS::IAM::InstanceProfile",
            "Properties": {
                "Path": "/",
                "Roles": [
                    {
                        "Ref": "TriggerPIBRole"
                    }
                ]
            }
        },


        "AutomationServiceRole": {
            "Type": "AWS::IAM::Role",
            "Properties": {
                "AssumeRolePolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [
                        {
                            "Effect": "Allow",
                            "Principal": {
                                "Service": [
                                    "ssm.amazonaws.com",
                                    "ec2.amazonaws.com"
                                ]
                            },
                            "Action": "sts:AssumeRole"
                        }
                    ]
                },
                "Path": "/",
                "Policies": [
                    {
                        "PolicyName": "passrole",
                        "PolicyDocument": {
                            "Version": "2012-10-17",
                            "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                        "iam:PassRole"
                                    ],
                                    "Resource": [
                                        {
                                            "Fn::GetAtt": [
                                                "ManagedInstanceRole",
                                                "Arn"
                                            ]
                                        }
                                        ,
                                         {
                                            "Fn::GetAtt": [
                                                "TriggerPIBRole",
                                                "Arn"
                                            ]
                                        }

                                    ]
                                }
                            ]
                        }
                    },
                    {
                        "PolicyName": "invokeLambdaFunction",
                        "PolicyDocument": {
                            "Version": "2012-10-17",
                            "Statement": [
                                {
                                    "Effect": "Allow",
                                    "Action": [
                                    "ec2:CreateImage",
                                     "ec2:DescribeImages",
                                     "ec2:StartInstances",
                                     "ec2:RunInstances",
                                     "ec2:StopInstances",
                                     "ec2:TerminateInstances",
                                     "ec2:DescribeInstanceStatus",
                                     "ec2:CreateTags",
                                     "ec2:DescribeTags",
                                     "ssm:*" ],
                                    "Resource": [ "*"]
                                }
                            ]
                        }
                    }
                ]
            }
        },
      "PIBNotificationTopic":{
         "Type":"AWS::SNS::Topic"
      },
      
      "PIBNotificationTopicSubscription" : {
      "Type" : "AWS::SNS::Subscription",
      "Properties" : {
        "Endpoint" : {"Ref":"EmailID"},
        "Protocol" : "email",
        "TopicArn" : {"Ref" : "PIBNotificationTopic"}
      }
    },

     "GoldenPIBAMIAutomationDoc": {
            "Type": "AWS::SSM::Document",
            
            "Properties": {
                "DocumentType": "Automation",
                "Content": {
                    "description": "This automation document triggers Golden AMI - PIB creation workflow.",
                    "schemaVersion": "0.3",
                    "assumeRole": {
                        "Fn::GetAtt": [
                            "AutomationServiceRole",
                            "Arn"
                        ]
                    },
                    "parameters": {
                        "sourceGoldenAMIid": {
                            "type": "String",
                            "description": "Source Golden AMI to be used by marketplaceimagebuild process ",
                            "default": ""
                        },
                       "buildServerAMIId": {
                            "type": "String",
                            "description": "AMI-ID of Amazon linux 2.0 AMI to instantiate for triggering marketplaceimagebuild  service",
                            "default": ""
                        },
                        "outputImageDescription": {
                            "type": "String",
                            "description": "Description of the output image.",
                            "default":  ""
                        },
                         
                          "fulfillmentOptionID": {
                            "type": "String",
                            "description": "The fulfillmentOptionID of the markteplace software.",
                            "default": ""
                        },

                        "subnetId": {
                            "type": "String",
                            "default":"",

                            "description": "A public subnet-id in which a server for triggering build process will be launched. "
                        },
                        "securityGroupId": {
                            "type": "String",
                            "default":"",
                            "description": "Security Group to be attached to the server that triggers build process. "
                        },
                        "instanceType": {
                            "type": "String",
                            "description": "A compatible instance-type for launching an instance",
                            "default": ""
                        },
                        "buildServerInstanceType": {
                            "type": "String",
                            "description": "A compatible instance-type for launching an instance",
                            "default": "t2.micro"
                        },
                        "targetAMIname": {
                            "type": "String",
                            "description": "Name for the golden AMI to be created",
                            "default": ""
                        }, 
                       "logBucketName": {
                            "type": "String",
                            "description": "Name of the s3 bucket in which logs will be written",
                            "default":  {
                                "Ref": "PrivateImageBuildConfigBucket"
                            }
                        }, 
                       
                        "TriggerImageProfile": {
                            "type": "String",
                            "description": "Instance Profile of the build server. Do not change the default value.",
                            "default": {
                                "Ref": "TriggerImageProfile"
                            }
                        },
                        "ManagedInstanceProfile": {
                            "type": "String",
                            "description": "ManagedInstanceProfile. Do not change the default value.",
                            "default": {
                                "Ref": "ManagedInstanceProfile"
                            }
                        } ,
                         "AutomationServiceRole": {
                            "type": "String",
                            "description": "AutomationServiceRole. Do not change the default value.",
                            "default": {
                                "Ref": "AutomationServiceRole"
                            }
                        } ,
                        "PIBNotificationTopic": {
                            "type": "String",
                            "description": "PIBNotificationTopic. Do not change the default value.",
                            "default": {
                                "Ref": "PIBNotificationTopic"
                            }
                        } ,
                         "SSMInstallationUserData": {
                            "type": "String",
                            "description": "Base64 encoded SSM installation user-data.",
                            "default": "IyEvYmluL2Jhc2gNCg0KZnVuY3Rpb24gZ2V0X2NvbnRlbnRzKCkgew0KICAgIGlmIFsgLXggIiQod2hpY2ggY3VybCkiIF07IHRoZW4NCiAgICAgICAgY3VybCAtcyAtZiAiJDEiDQogICAgZWxpZiBbIC14ICIkKHdoaWNoIHdnZXQpIiBdOyB0aGVuDQogICAgICAgIHdnZXQgIiQxIiAtTyAtDQogICAgZWxzZQ0KICAgICAgICBkaWUgIk5vIGRvd25sb2FkIHV0aWxpdHkgKGN1cmwsIHdnZXQpIg0KICAgIGZpDQp9DQoNCnJlYWRvbmx5IElERU5USVRZX1VSTD0iaHR0cDovLzE2OS4yNTQuMTY5LjI1NC8yMDE2LTA2LTMwL2R5bmFtaWMvaW5zdGFuY2UtaWRlbnRpdHkvZG9jdW1lbnQvIg0KcmVhZG9ubHkgVFJVRV9SRUdJT049JChnZXRfY29udGVudHMgIiRJREVOVElUWV9VUkwiIHwgYXdrIC1GXCIgJy9yZWdpb24vIHsgcHJpbnQgJDQgfScpDQpyZWFkb25seSBERUZBVUxUX1JFR0lPTj0idXMtZWFzdC0xIg0KcmVhZG9ubHkgUkVHSU9OPSIke1RSVUVfUkVHSU9OOi0kREVGQVVMVF9SRUdJT059Ig0KDQpyZWFkb25seSBTQ1JJUFRfTkFNRT0iYXdzLWluc3RhbGwtc3NtLWFnZW50Ig0KIFNDUklQVF9VUkw9Imh0dHBzOi8vYXdzLXNzbS1kb3dubG9hZHMtJFJFR0lPTi5zMy5hbWF6b25hd3MuY29tL3NjcmlwdHMvJFNDUklQVF9OQU1FIg0KDQppZiBbICIkUkVHSU9OIiA9ICJjbi1ub3J0aC0xIiBdOyB0aGVuDQogIFNDUklQVF9VUkw9Imh0dHBzOi8vYXdzLXNzbS1kb3dubG9hZHMtJFJFR0lPTi5zMy5jbi1ub3J0aC0xLmFtYXpvbmF3cy5jb20uY24vc2NyaXB0cy8kU0NSSVBUX05BTUUiDQpmaQ0KDQppZiBbICIkUkVHSU9OIiA9ICJ1cy1nb3Ytd2VzdC0xIiBdOyB0aGVuDQogIFNDUklQVF9VUkw9Imh0dHBzOi8vYXdzLXNzbS1kb3dubG9hZHMtJFJFR0lPTi5zMy11cy1nb3Ytd2VzdC0xLmFtYXpvbmF3cy5jb20vc2NyaXB0cy8kU0NSSVBUX05BTUUiDQpmaQ0KDQpjZCAvdG1wDQpGSUxFX1NJWkU9MA0KTUFYX1JFVFJZX0NPVU5UPTMNClJFVFJZX0NPVU5UPTANCg0Kd2hpbGUgWyAkUkVUUllfQ09VTlQgLWx0ICRNQVhfUkVUUllfQ09VTlQgXSA7IGRvDQogIGVjaG8gQVdTLVVwZGF0ZUxpbnV4QW1pOiBEb3dubG9hZGluZyBzY3JpcHQgZnJvbSAkU0NSSVBUX1VSTA0KICBnZXRfY29udGVudHMgIiRTQ1JJUFRfVVJMIiA+ICIkU0NSSVBUX05BTUUiDQogIEZJTEVfU0laRT0kKGR1IC1rIC90bXAvJFNDUklQVF9OQU1FIHwgY3V0IC1mMSkNCiAgZWNobyBBV1MtVXBkYXRlTGludXhBbWk6IEZpbmlzaGVkIGRvd25sb2FkaW5nIHNjcmlwdCwgc2l6ZTogJEZJTEVfU0laRQ0KICBpZiBbICRGSUxFX1NJWkUgLWd0IDAgXTsgdGhlbg0KICAgIGJyZWFrDQogIGVsc2UNCiAgICBpZiBbWyAkUkVUUllfQ09VTlQgLWx0IE1BWF9SRVRSWV9DT1VOVCBdXTsgdGhlbg0KICAgICAgUkVUUllfQ09VTlQ9JCgoUkVUUllfQ09VTlQrMSkpOw0KICAgICAgZWNobyBBV1MtVXBkYXRlTGludXhBbWk6IEZpbGVTaXplIGlzIDAsIHJldHJ5Q291bnQ6ICRSRVRSWV9DT1VOVA0KICAgIGZpDQogIGZpIA0KZG9uZQ0KDQppZiBbICRGSUxFX1NJWkUgLWd0IDAgXTsgdGhlbg0KICBjaG1vZCAreCAiJFNDUklQVF9OQU1FIg0KICBlY2hvIEFXUy1VcGRhdGVMaW51eEFtaTogUnVubmluZyBVcGRhdGVTU01BZ2VudCBzY3JpcHQgbm93IC4uLi4NCiAgLi8iJFNDUklQVF9OQU1FIiAtLXJlZ2lvbiAiJFJFR0lPTiINCmVsc2UNCiAgZWNobyBBV1MtVXBkYXRlTGludXhBbWk6IFVuYWJsZSB0byBkb3dubG9hZCBzY3JpcHQsIHF1aXR0aW5nIC4uLi4NCmZp"
                        }
                    },
                    "mainSteps": [
                        {
                            "name": "startInstances",
                            "action": "aws:runInstances",
                            "timeoutSeconds": 3600,
                            "maxAttempts": 1,
                            "onFailure": "step:stopInstance",
                            "inputs": {
                                "ImageId": "{{ buildServerAMIId }}",
                                "InstanceType": "{{buildServerInstanceType}}",
                                "MinInstanceCount": 1,
                                "MaxInstanceCount": 1,
                                "SubnetId": "{{ subnetId }}",
                                "SecurityGroupIds": [
                                    "{{ securityGroupId }}"
                                ],
                                 "UserData": "{{SSMInstallationUserData}}",
                                 "IamInstanceProfileName": "{{ TriggerImageProfile }}",
                                 "TagSpecifications":[
                                   {
                                      "ResourceType":"instance",
                                      "Tags":[
                                         {
                                            "Key":"Name",
                                            "Value":"PIB-Build-trigger-Server"
                                         }
                                      ]
                                   }
                                ]
                            }
                        },

                        {
                            "name": "downloadMarketplaceModel",
                            "action": "aws:runCommand",
                            "maxAttempts": 3,
                            "timeoutSeconds": 3600,
                            "onFailure": "step:stopInstance",
                            "inputs": {
                                "DocumentName": "AWS-RunShellScript",
                                "InstanceIds": [
                                    "{{startInstances.InstanceIds}}"
                                ],
                                "Parameters": {
                                    "commands": [
                                        "curl https://s3.amazonaws.com/marketplace-sa-resources/marketplaceimagebuild-2017-12-15.normal-1.json -o marketplaceimagebuild-2017-12-15.normal-1.json"
                                    ]
                                }
                            }
                        },
                         {
                            "name": "registerCLI",
                            "action": "aws:runCommand",
                            "maxAttempts": 3,
                            "timeoutSeconds": 3600,
                            "onFailure": "step:stopInstance",
                            "inputs": {
                                "DocumentName": "AWS-RunShellScript",
                                "InstanceIds": [
                                    "{{startInstances.InstanceIds}}"
                                ],
                                "Parameters": {
                                    "commands": [
                                        "aws configure add-model --service-model file://marketplaceimagebuild-2017-12-15.normal-1.json --service-name marketplaceimagebuild"
                                    ]
                                }
                            }
                        },
                         {
                            "name": "TriggerPIBImageCreation",
                            "action": "aws:runCommand",
                            "maxAttempts": 3,
                            "timeoutSeconds": 3600,
                            "onFailure": "step:stopInstance",
                            "inputs": {
                                "DocumentName": "AWS-RunShellScript",
                                "InstanceIds": [
                                    "{{startInstances.InstanceIds}}"
                                ],
                                "Parameters": {
                                    "commands": [
                                        "aws marketplaceimagebuild start-build --input-fulfillment-option-ids \"{{fulfillmentOptionID}}\" --output-image-name \"{{targetAMIname}}\" --input-image-id \"{{sourceGoldenAMIid}}\" --output-image-description \"{{outputImageDescription}}\" --input-instance-type \"{{instanceType}}\" --output-installation-log-s3-bucket-name \"{{logBucketName}}\" --input-automation-role \"{{AutomationServiceRole}}\" --input-instance-profile \"{{ManagedInstanceProfile}}\" --region \"{{global:REGION}}\" --input-sns-topic-arn \"{{PIBNotificationTopic}}\""
                                    ]
                                }
                            }
                        },
                        {
                            "name": "stopInstance",
                            "action": "aws:changeInstanceState",
                            "timeoutSeconds": 1200,
                            "maxAttempts": 1,
                            "onFailure": "Abort",
                            "inputs": {
                                "InstanceIds": [
                                    "{{ startInstances.InstanceIds }}"
                                ],
                                "DesiredState": "terminated"
                            }
                        }
                       
                    ],
                    "outputs": [
                        "TriggerPIBImageCreation.Output"
                    ]
                }
            }
        }
    },
    "Outputs": {
        "ManagedInstanceRole": {
            "Description": "The name of the ManagedInstanceRole.",
            "Value": {
                "Ref": "ManagedInstanceRole"
            }
        },
        "AutomationServiceRole": {
            "Description": "The Name of the automation service role.",
            "Value": {
                "Ref": "AutomationServiceRole"
            }
        },
         "PIBBucket": {
            "Description": "The Name of the bucket created for PIB.",
            "Value": {
                "Ref": "PrivateImageBuildConfigBucket"
            }
        },
           "GoldenPIBAMIAutomationDoc": {
            "Description": "The PIB automation doc.",
            "Value": {
                "Ref": "GoldenPIBAMIAutomationDoc"
            }
        },
        "PIBNotificationTopic": {
            "Description": "The notification topic on which PIB will publish notifications.",
            "Value": {
                "Ref": "PrivateImageBuildConfigBucket"
            }
        },
        "SampleCommandTemplateForInvokingPIB":
        {
          "Value": { "Fn::Join": 
                                      [
                                          "",
                                          [
                                              "aws marketplaceimagebuild start-build", " --input-fulfillment-option-ids \"specify-fulfillment-ids-here\"",
                                              " --output-image-name \"specify-target-image-name-here\"",
                                              " --input-image-id \"specify-image-id-here\"",
                                              " --output-image-description \"specify-image-description-here\"",
                                              " --input-instance-type \"specify-instance-type-here\"",
                                              " --output-installation-log-s3-bucket-name \"",
                                              {
                                                  "Ref":"PrivateImageBuildConfigBucket"
                                              },
                                              "\"",
                                              " --input-automation-role \"",
                                              {
                                                  "Ref":"AutomationServiceRole"
                                              },
                                              "\"",
                                              " --input-instance-profile \"",
                                              {
                                                  "Ref":"ManagedInstanceProfile"
                                              },
                                              "\"",
                                              " --region \"specify-region-here\"",

                                              " --input-sns-topic-arn \"",
                                              {
                                                  "Ref":"PIBNotificationTopic"
                                              },
                                              "\"",
                                              
                                              
                                          ]
                                      ]} 
        }
}
}
