Example #1
0
    public MyStack()
    {
        // Create an Azure Resource Group
        var resourceGroup = new ResourceGroup("pulumiresourcegroup");

        // Create an Azure Storage Account
        var storageAccount = new Account("pulumistorage", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard"
        });

        // Create AppService Plan
        var appServicePlan = new Plan("asp", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "FunctionApp",
            Sku  = new PlanSkuArgs
            {
                Tier = "Dynamic",
                Size = "Y1",
            }
        });

        // Create Container
        var container = new Container("zips", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private"
        });

        // Create BlobStorage
        var blob = new Blob("zip", new BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = container.Name,
            Type   = "Block",
            Source = new FileArchive("./functions/bin/Debug/netcoreapp3.1/publish")
        });

        var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        // Create FunctionApp
        var app = new FunctionApp("function-app", new FunctionAppArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            AppSettings       =
            {
                { "runtime",                  "dotnet"    },
                { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },
            },
            StorageAccountName      = storageAccount.Name,
            StorageAccountAccessKey = storageAccount.PrimaryAccessKey,
            Version = "~3"
        });

        this.Endpoint = Output.Format($"https://{app.DefaultHostname}/api/Hello?name=Pulumi");
    }
    public ArchiveFunctionApp(string name, ArchiveFunctionAppArgs args, ResourceOptions?options = null)
        : base("examples:azure:ArchiveFunctionApp", name, options)
    {
        var opts = CustomResourceOptions.Merge(options, new CustomResourceOptions {
            Parent = this
        });

        var storageAccount = new Account($"sa{args.Location}", new AccountArgs
        {
            ResourceGroupName      = args.ResourceGroupName,
            Location               = args.Location,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard",
        }, opts);

        var appServicePlan = new Plan($"asp-{args.Location}", new PlanArgs
        {
            ResourceGroupName = args.ResourceGroupName,
            Location          = args.Location,
            Kind = "FunctionApp",
            Sku  = new PlanSkuArgs
            {
                Tier = "Dynamic",
                Size = "Y1",
            },
        }, opts);

        var container = new Container($"zips-{args.Location}", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private",
        }, opts);

        var blob = new ZipBlob($"zip-{args.Location}", new ZipBlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = container.Name,
            Type    = "block",
            Content = args.Archive,
        }, opts);

        var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        args.AppSettings.Add("runtime", "dotnet");
        args.AppSettings.Add("WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl);

        var app = new FunctionApp($"app-{args.Location}", new FunctionAppArgs
        {
            ResourceGroupName       = args.ResourceGroupName,
            Location                = args.Location,
            AppServicePlanId        = appServicePlan.Id,
            AppSettings             = args.AppSettings,
            StorageConnectionString = storageAccount.PrimaryConnectionString,
            Version = "~2",
        }, opts);

        this.AppId = app.Id;
    }
Example #3
0
    static Task <int> Main()
    {
        return(Deployment.RunAsync(() => {
            var resourceGroup = new ResourceGroup("functions-rg");

            var storageAccount = new Account("sa", new AccountArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AccountReplicationType = "LRS",
                AccountTier = "Standard",
            });

            var appServicePlan = new Plan("asp", new PlanArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Kind = "FunctionApp",
                Sku = new PlanSkuArgs
                {
                    Tier = "Dynamic",
                    Size = "Y1",
                },
            });

            var container = new Container("zips", new ContainerArgs
            {
                StorageAccountName = storageAccount.Name,
                ContainerAccessType = "private",
            });

            var blob = new ZipBlob("zip", new ZipBlobArgs
            {
                StorageAccountName = storageAccount.Name,
                StorageContainerName = container.Name,
                Type = "block",
                Content = new FileArchive("./functions/bin/Debug/netcoreapp3.0/publish"),
            });

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            var app = new FunctionApp("app", new FunctionAppArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AppServicePlanId = appServicePlan.Id,
                AppSettings =
                {
                    { "runtime",                  "dotnet"    },
                    { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },
                },
                StorageConnectionString = storageAccount.PrimaryConnectionString,
                Version = "~3",
            });

            return new Dictionary <string, object>
            {
                { "endpoint", Output.Format($"https://{app.DefaultHostname}/api/Hello?name=Pulumi") },
            };
        }));
    }
Example #4
0
    static Task <int> Main(string[] args)
    {
        return(Deployment.RunAsync(() => {
            var resourceGroup = new ResourceGroup("appservice-rg");

            var storageAccount = new Account("sa", new AccountArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AccountReplicationType = "LRS",
                AccountTier = "Standard",
            });

            var appServicePlan = new Plan("asp", new PlanArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Kind = "App",
                Sku = new PlanSkuArgs
                {
                    Tier = "Basic",
                    Size = "B1",
                },
            });

            var container = new Container("zips", new ContainerArgs
            {
                StorageAccountName = storageAccount.Name,
                ContainerAccessType = "private",
            });

            var blob = new Blob("zip", new BlobArgs
            {
                StorageAccountName = storageAccount.Name,
                StorageContainerName = container.Name,
                Type = "Block",
                Source = new FileArchive("wwwroot")
            });

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            var app = new AppService("app", new AppServiceArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AppServicePlanId = appServicePlan.Id,
                AppSettings =
                {
                    { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },
                },
            });

            return new Dictionary <string, object>
            {
                { "url", Output.Format($"https://{app.DefaultSiteHostname}") },
            };
        }));
    }
Example #5
0
    public ArchiveFunctionApp(string name, ArchiveFunctionAppArgs args, ComponentResourceOptions?options = null)
        : base("examples:azure:ArchiveFunctionApp", name, options)
    {
        var opts = new CustomResourceOptions {
            Parent = this
        };

        var storageAccount = new Account("sa", new AccountArgs
        {
            ResourceGroupName      = args.ResourceGroupName,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard",
        }, opts);

        var appServicePlan = new Plan("asp", new PlanArgs
        {
            ResourceGroupName = args.ResourceGroupName,
            Kind = "FunctionApp",
            Sku  = new PlanSkuArgs
            {
                Tier = "Dynamic",
                Size = "Y1",
            },
        }, opts);

        var container = new Container("zips", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private",
        }, opts);

        var blob = new Blob("zip", new BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = container.Name,
            Type   = "Block",
            Source = args.Archive
        }, opts);

        var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        var app = new FunctionApp("app", new FunctionAppArgs
        {
            ResourceGroupName = args.ResourceGroupName,
            AppServicePlanId  = appServicePlan.Id,
            AppSettings       =
            {
                { "runtime",                  "dotnet"    },
                { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },
            },
            StorageConnectionString = storageAccount.PrimaryConnectionString,
            Version = "~2"
        }, opts);
    }
Example #6
0
        private static FunctionApp CreateFunctionApp(
            string name,
            Config config,
            ResourceGroup resourceGroup,
            Account storageAccount,
            string codePath,
            Dictionary <string, Output <string> >?additionalSettings = null)
        {
            var userServicePlan = new Plan(name, new PlanArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Kind = "FunctionApp",
                Sku  = new PlanSkuArgs
                {
                    Tier = "Dynamic",
                    Size = "Y1"
                }
            });

            var container = new Container($"{name}-zips", new ContainerArgs
            {
                StorageAccountName  = storageAccount.Name,
                ContainerAccessType = "private"
            });

            var blob = new Blob($"{name}-zip", new BlobArgs
            {
                StorageAccountName   = storageAccount.Name,
                StorageContainerName = container.Name,
                Type   = "Block",
                Source = new FileArchive(codePath)
            });

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            var appSettings = new InputMap <string>
            {
                { "FUNCTIONS_EXTENSION_VERSION", "~3" },
                { "FUNCTIONS_WORKER_RUNTIME", "dotnet" },
                { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },

                { "JwtSecretKey", config.RequireSecret("JWT_SECRET_KEY") },
                { "JwtIssuer", config.Require("JWT_ISSUER") },
                { "JwtAudience", config.Require("JWT_AUDIENCE") },
                { "JwtExpires", config.Require("JWT_EXPIRES") },

                { "TwilioAccountSid", config.Require("TWILIO_ACCOUNT_SID") },
                { "TwilioApiSid", config.Require("TWILIO_API_SID") },
                { "TwilioApiSecret", config.RequireSecret("TWILIO_API_SECRET") },
            };

            if (additionalSettings is { })
Example #7
0
        public static Dictionary <string, object> Run()
        {
            var resourceGroup = new ResourceGroup("dotnet-rg", new ResourceGroupArgs
            {
                Location = "West Europe"
            });

            var cosmosapp = new CosmosApp("capp", new CosmosAppArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Locations         = new[] { resourceGroup.Location },
            });

            var storageAccount = new Account("sa", new AccountArgs
            {
                ResourceGroupName      = resourceGroup.Name,
                AccountReplicationType = "LRS",
                AccountTier            = "Standard",
            });

            var appServicePlan = new Plan("asp", new PlanArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Kind = "App",
                Sku  = new PlanSkuArgs
                {
                    Tier = "Basic",
                    Size = "B1",
                },
            });

            var container = new Container("c", new ContainerArgs
            {
                StorageAccountName  = storageAccount.Name,
                ContainerAccessType = "private",
            });

            var blob = new ZipBlob("zip", new ZipBlobArgs
            {
                StorageAccountName   = storageAccount.Name,
                StorageContainerName = container.Name,
                Type    = "block",
                Content = new FileArchive("wwwroot"),
            });

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            //var username = "******"; // TODO: Pulumi.Config
            //var password = "******";
            //var sqlServer = new SqlServer("sql", new SqlServerArgs
            //{
            //    ResourceGroupName = resourceGroup.Name,
            //    AdministratorLogin = username,
            //    AdministratorLoginPassword = password,
            //    Version = "12.0",
            //});

            //var database = new Database("db", new DatabaseArgs
            //{
            //    ResourceGroupName = resourceGroup.Name,
            //    ServerName = sqlServer.Name,
            //    RequestedServiceObjectiveName = "S0",
            //});

            var app = new AppService("app", new AppServiceArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AppServicePlanId  = appServicePlan.Id,
                AppSettings       =
                {
                    { "WEBSITE_RUN_FROM_ZIP", codeBlobUrl },
                },
                //ConnectionStrings = new[]
                //{
                //    new AppService.ConnectionStringArgs
                //    {
                //        Name = "db",
                //        Type = "SQLAzure",
                //        Value = Output.All<string>(sqlServer.Name, database.Name).Apply(values =>
                //        {
                //            return $"Server= tcp:${values[0]}.database.windows.net;initial catalog=${values[1]};userID=${username};password=${password};Min Pool Size=0;Max Pool Size=30;Persist Security Info=true;";
                //        }),
                //    },
                //},
            });

            return(new Dictionary <string, object>
            {
                { "endpoint", app.DefaultSiteHostname },
            });
        }
Example #8
0
        public Step3Start()
        {
            const string prefix   = Common.Prefix;
            var          config   = new Config();
            var          location = config.Get("location") ?? "australiaeast";

            #region Resource Group
            var resourceGroup = new ResourceGroup($"{prefix}-{Deployment.Instance.StackName}", new ResourceGroupArgs()
            {
                Name     = $"{prefix}-{Deployment.Instance.StackName}",
                Location = location
            });
            var name = $"{prefix}{Deployment.Instance.StackName}web";
            #endregion

            #region Static Website
            var staticWebsiteStorageAccount = new Pulumi.Azure.Storage.Account(
                name,
                new Pulumi.Azure.Storage.AccountArgs
            {
                Name = name,
                ResourceGroupName      = resourceGroup.Name,
                EnableHttpsTrafficOnly = true,
                AccountReplicationType = "LRS",
                AccountTier            = "Standard",
                AccountKind            = "StorageV2",
                AccessTier             = "Hot"
            });

            WebContainer =
                staticWebsiteStorageAccount.PrimaryBlobConnectionString.Apply(async v => await EnableStaticSites(v));
            StaticWebsiteConnection = staticWebsiteStorageAccount.PrimaryBlobConnectionString;
            #endregion

            #region Cosmos DB
            var cosmosDatabaseOutput = CosmosDatabase.Run(
                resourceGroup.Name, prefix, resourceGroup.Location);
            #endregion

            #region Azure Function
            #region Storage Account
            var storageAccount = new Account($"sa{prefix}{Deployment.Instance.StackName}",
                                             new AccountArgs
            {
                Name = $"sa{prefix}{Deployment.Instance.StackName}",
                ResourceGroupName      = resourceGroup.Name,
                Location               = resourceGroup.Location,
                AccountReplicationType = "LRS",
                AccountTier            = "Standard"
            });
            #endregion

            #region App Service Plan
            var appServicePlan = new Plan($"asp-{prefix}{Deployment.Instance.StackName}",
                                          new PlanArgs
            {
                Name = $"asp-{prefix}{Deployment.Instance.StackName}",
                ResourceGroupName = resourceGroup.Name,
                Location          = resourceGroup.Location,
                Kind = "FunctionApp",
                Sku  = new PlanSkuArgs
                {
                    Tier = "Dynamic",
                    Size = "Y1"
                }
            });
            #endregion

            #region Storage Container
            var container = new Container($"func-code", new ContainerArgs
            {
                StorageAccountName  = storageAccount.Name,
                ContainerAccessType = "private",
            });
            #endregion

            #region Function Zip Blob
            var functionAppFileLocation = "../TeamTimeZones/bin/Debug/netcoreapp3.1/publish/";
            var blob = new Blob($"func", new BlobArgs
            {
                StorageAccountName   = storageAccount.Name,
                StorageContainerName = container.Name,
                Type   = "block",
                Source = new FileArchive(functionAppFileLocation),
            });
            #endregion

            #region Function App
            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);
            var app         = new FunctionApp($"app-{prefix}",
                                              new FunctionAppArgs
            {
                Name = $"app-{prefix}",
                ResourceGroupName       = resourceGroup.Name,
                Location                = resourceGroup.Location,
                AppServicePlanId        = appServicePlan.Id,
                StorageConnectionString = storageAccount.PrimaryConnectionString,
                Version     = "~3",
                AppSettings = new InputMap <string>
                {
                    { "runtime", "dotnet" },
                    { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },
                    { "db-account-endpoint", cosmosDatabaseOutput["db-account-endpoint"].Apply(x => x.ToString()) },
                    { "db-account-key", cosmosDatabaseOutput["db-account-key"].Apply(x => x.ToString()) }
                },
                SiteConfig = new FunctionAppSiteConfigArgs
                {
                    Cors = new FunctionAppSiteConfigCorsArgs
                    {
                        AllowedOrigins = "*"
                    }
                }
            });

            this.FunctionAppEndPoint = app.DefaultHostname;
            #endregion
            #endregion
        }
Example #9
0
    public AppServiceStack()
    {
        var resourceGroup = new ResourceGroup("appservice-rg");

        var storageAccount = new Account("sa", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard",
        });

        var appServicePlan = new Plan("asp", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "App",
            Sku  = new PlanSkuArgs
            {
                Tier = "Basic",
                Size = "B1",
            },
        });

        var container = new Container("zips", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private",
        });

        var blob = new Blob("zip", new BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = container.Name,
            Type   = "Block",
            Source = new FileArchive("wwwroot"),
        });

        var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        var config    = new Config();
        var username  = config.Get("sqlAdmin") ?? "pulumi";
        var password  = config.RequireSecret("sqlPassword");
        var sqlServer = new SqlServer("sql", new SqlServerArgs
        {
            ResourceGroupName          = resourceGroup.Name,
            AdministratorLogin         = username,
            AdministratorLoginPassword = password,
            Version = "12.0",
        });

        var database = new Database("db", new DatabaseArgs
        {
            ResourceGroupName             = resourceGroup.Name,
            ServerName                    = sqlServer.Name,
            RequestedServiceObjectiveName = "S0",
        });

        var app = new AppService("app", new AppServiceArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            AppSettings       =
            {
                { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },
            },
Example #10
0
    static Task <int> Main()
    {
        return(Deployment.RunAsync(async() => {
            var resourceGroup = new ResourceGroup("keyvault-rg");

            // Create a storage account for Blobs
            var storageAccount = new Account("storage", new AccountArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AccountReplicationType = "LRS",
                AccountTier = "Standard",
            });

            // The container to put our files into
            var storageContainer = new Container("files", new ContainerArgs
            {
                StorageAccountName = storageAccount.Name,
                ContainerAccessType = "private",
            });

            // Azure SQL Server that we want to access from the application
            var administratorLoginPassword = new RandomPassword("password",
                                                                new RandomPasswordArgs {
                Length = 16, Special = true
            }).Result;
            var sqlServer = new SqlServer("sqlserver", new SqlServerArgs
            {
                ResourceGroupName = resourceGroup.Name,
                // The login and password are required but won't be used in our application
                AdministratorLogin = "******",
                AdministratorLoginPassword = administratorLoginPassword,
                Version = "12.0",
            });

            // Azure SQL Database that we want to access from the application
            var database = new Database("db", new DatabaseArgs
            {
                ResourceGroupName = resourceGroup.Name,
                ServerName = sqlServer.Name,
                RequestedServiceObjectiveName = "S0",
            });

            // The connection string that has no credentials in it: authertication will come through MSI
            var connectionString = Output.Format($"Server=tcp:{sqlServer.Name}.database.windows.net;Database={database.Name};");

            // A file in Blob Storage that we want to access from the application
            var textBlob = new Blob("text", new BlobArgs
            {
                StorageAccountName = storageAccount.Name,
                StorageContainerName = storageContainer.Name,
                Type = "block",
                Source = "./README.md",
            });

            // A plan to host the App Service
            var appServicePlan = new Plan("asp", new PlanArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Kind = "App",
                Sku = new PlanSkuArgs
                {
                    Tier = "Basic",
                    Size = "B1",
                },
            });

            // ASP.NET deployment package
            var blob = new ZipBlob("zip", new ZipBlobArgs
            {
                StorageAccountName = storageAccount.Name,
                StorageContainerName = storageContainer.Name,
                Type = "block",
                Content = new FileArchive("./webapp/bin/Debug/netcoreapp2.2/publish"),
            });

            var clientConfig = await Pulumi.Azure.Core.Invokes.GetClientConfig();
            var tenantId = clientConfig.TenantId;
            var currentPrincipal = clientConfig.ObjectId;

            // Key Vault to store secrets (e.g. Blob URL with SAS)
            var vault = new KeyVault("vault", new KeyVaultArgs
            {
                ResourceGroupName = resourceGroup.Name,
                SkuName = "standard",
                TenantId = tenantId,
                AccessPolicies =
                {
                    new KeyVaultAccessPoliciesArgs
                    {
                        TenantId = tenantId,
                        // The current principal has to be granted permissions to Key Vault so that it can actually add and then remove
                        // secrets to/from the Key Vault. Otherwise, 'pulumi up' and 'pulumi destroy' operations will fail.
                        ObjectId = currentPrincipal,
                        SecretPermissions ={ "delete",                         "get", "list", "set" },
                    }
                },
            });

            // Put the URL of the zip Blob to KV
            var secret = new Secret("deployment-zip", new SecretArgs
            {
                KeyVaultId = vault.Id,
                Value = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount),
            });
            var secretUri = Output.Format($"{secret.VaultUri}secrets/{secret.Name}/{secret.Version}");


            // The application hosted in App Service
            var app = new AppService("app", new AppServiceArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AppServicePlanId = appServicePlan.Id,
                // A system-assigned managed service identity to be used for authentication and authorization to the SQL Database and the Blob Storage
                Identity = new AppServiceIdentityArgs {
                    Type = "SystemAssigned"
                },

                AppSettings =
                {
                    // Website is deployed from a URL read from the Key Vault
                    { "WEBSITE_RUN_FROM_ZIP", Output.Format($"@Microsoft.KeyVault(SecretUri={secretUri})") },

                    // Note that we simply provide the URL without SAS or keys
                    { "StorageBlobUrl",       textBlob.Url                                                 },
                },
                ConnectionStrings =
                {
                    new AppServiceConnectionStringsArgs
                    {
                        Name = "db",
                        Type = "SQLAzure",
                        Value = connectionString,
                    },
                },
            });

            // Work around a preview issue https://github.com/pulumi/pulumi-azure/issues/192
            var principalId = app.Identity.Apply(id => id.PrincipalId ?? "11111111-1111-1111-1111-111111111111");

            // Grant App Service access to KV secrets
            var policy = new AccessPolicy("app-policy", new AccessPolicyArgs
            {
                KeyVaultId = vault.Id,
                TenantId = tenantId,
                ObjectId = principalId,
                SecretPermissions = { "get" },
            });

            // Make the App Service the admin of the SQL Server (double check if you want a more fine-grained security model in your real app)
            var sqlAdmin = new ActiveDirectoryAdministrator("adadmin", new ActiveDirectoryAdministratorArgs
            {
                ResourceGroupName = resourceGroup.Name,
                TenantId = tenantId,
                ObjectId = principalId,
                Login = "******",
                ServerName = sqlServer.Name,
            });

            // Grant access from App Service to the container in the storage
            var blobPermission = new Assignment("readblob", new AssignmentArgs
            {
                PrincipalId = principalId,
                Scope = Output.Format($"{storageAccount.Id}/blobServices/default/containers/{storageContainer.Name}"),
                RoleDefinitionName = "Storage Blob Data Reader",
            });

            // Add SQL firewall exceptions
            var firewallRules = app.OutboundIpAddresses.Apply(
                ips => ips.Split(",").Select(
                    ip => new FirewallRule($"FR{ip}", new FirewallRuleArgs
            {
                ResourceGroupName = resourceGroup.Name,
                StartIpAddress = ip,
                EndIpAddress = ip,
                ServerName = sqlServer.Name,
            })
                    ).ToList());

            return new Dictionary <string, object>
            {
                { "endpoint", Output.Format($"https://{app.DefaultSiteHostname}") },
            };
        }));
    }
    public FunctionsStack()
    {
        var resourceGroup = new ResourceGroup("functions-rg");

        var storageAccount = new Account("sa", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard"
        });

        var appServicePlan = new Plan("functions-linux-asp", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,

            // Run on Linux
            Kind = "Linux",

            // Premium SKU
            Sku = new PlanSkuArgs
            {
                Tier = "PremiumV2",
                Size = "P1v2"
            },

            // For Linux, you need to change the plan to have Reserved = true property.
            Reserved = true
        });

        var container = new Container("zips", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private"
        });

        var blob = new Blob("zip", new BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = container.Name,
            Type   = "Block",
            Source = new FileArchive("./functions")
        });

        var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        // Application insights
        var insights = new Insights("functions-ai", new InsightsArgs
        {
            ResourceGroupName = resourceGroup.Name,
            ApplicationType   = "web"
        });

        var app = new FunctionApp("app", new FunctionAppArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            AppSettings       =
            {
                { "runtime",                               "python"                                                           },
                { "FUNCTIONS_WORKER_RUNTIME",              "python"                                                           },
                { "WEBSITE_RUN_FROM_PACKAGE",              codeBlobUrl                                                        },
                { "APPLICATIONINSIGHTS_CONNECTION_STRING", Output.Format($"InstrumentationKey={insights.InstrumentationKey}") }
            },
            StorageAccountName      = storageAccount.Name,
            StorageAccountAccessKey = storageAccount.PrimaryAccessKey,
            Version    = "~3",
            OsType     = "linux",
            SiteConfig = new FunctionAppSiteConfigArgs
            {
                AlwaysOn       = true,
                LinuxFxVersion = "DOCKER|mcr.microsoft.com/azure-functions/python:2.0"
            }
        });

        this.Endpoint = Output.Format($"https://{app.DefaultHostname}/api/Hello?name=Pulumi");
    }
        public AzureFunctionStack()
        {
            bool newResourceGroup  = false;
            bool newappServicePlan = false;

            ResourceGroup resourceGroup;

            if (newResourceGroup)
            {
                resourceGroup = new ResourceGroup("linux-app-service");
            }
            else
            {
                resourceGroup = ResourceGroup.Get("linux-app-service", "/subscriptions/ae9255af-d099-4cdc-90a7-241ccb29df68/resourceGroups/linux-app-service");
            }

            var storageAccount = new Account("stefsapulumi", new AccountArgs
            {
                ResourceGroupName      = resourceGroup.Name,
                AccountReplicationType = StorageAccountReplicationTypes.LocallyRedundantStorage,
                AccountTier            = StorageAccountTiers.Standard
            });

            Plan appServicePlan;

            if (newappServicePlan)
            {
                appServicePlan = new Plan("linux-app-service-plan", new PlanArgs
                {
                    ResourceGroupName = resourceGroup.Name,

                    // Possible values are `Windows` (also available as `App`), `Linux`, `elastic` (for Premium Consumption) and `FunctionApp` (for a Consumption Plan).
                    Kind = AppServicePlanSkuKinds.Linux,

                    Sku = new PlanSkuArgs
                    {
                        Tier = AppServicePlanTiers.PremiumV2,
                        Size = AppServicePlanSkuSizes.PremiumV2Small
                    },

                    // For Linux, you need to change the plan to have Reserved = true property.
                    Reserved = true
                });
            }
            else
            {
                appServicePlan = Plan.Get("linux-app-service-plan", "/subscriptions/ae9255af-d099-4cdc-90a7-241ccb29df68/resourceGroups/linux-app-service/providers/Microsoft.Web/serverfarms/linux-app-service-plan");
            }

            var container = new Container("azure-function-zips", new ContainerArgs
            {
                StorageAccountName  = storageAccount.Name,
                ContainerAccessType = ContainerAccessTypes.Private
            });

            string currentDirectory = Directory.GetCurrentDirectory();

            Console.WriteLine($"currentDirectory = {currentDirectory}");

            var rootDirectory = Directory.GetParent(currentDirectory);

            Console.WriteLine($"rootDirectory = {rootDirectory}");

            string functionsAppPublishDirectory = Path.Combine(rootDirectory.FullName, "publish");

            Console.WriteLine($"functionsAppPublishDirectory = {functionsAppPublishDirectory}");

            var blob = new Blob("azure-function-zip", new BlobArgs
            {
                StorageAccountName   = storageAccount.Name,
                StorageContainerName = container.Name,
                Type = BlobTypes.Block,

                // The published folder contains a 'zip' file
                Source = new FileArchive(functionsAppPublishDirectory)
            });

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            var insights = new Insights("stef-ai-fa-l-v3p", new InsightsArgs
            {
                ResourceGroupName = resourceGroup.Name,
                ApplicationType   = InsightsApplicationTypes.Web
            });

            var functionApp = new FunctionApp("stef-function-app-linux-v3p", new FunctionAppArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AppServicePlanId  = appServicePlan.Id,
                AppSettings       =
                {
                    { "runtime",                               FunctionAppWorkerRuntimes.DotNet                                   },
                    { "DOCKER_REGISTRY_SERVER_URL",            "https://index.docker.io"                                          },
                    { "WEBSITE_ENABLE_SYNC_UPDATE_SITE",       "true"                                                             },
                    { "WEBSITES_ENABLE_APP_SERVICE_STORAGE",   "true"                                                             },
                    { "WEBSITE_RUN_FROM_PACKAGE",              codeBlobUrl                                                        },

                    /*
                     * App Insights configuration will use the APPLICATIONINSIGHTS_CONNECTION_STRING app setting if it is set.
                     * APPINSIGHTS_INSTRUMENTATIONKEY is the fallback and continues to work as-is.
                     */
                    { "APPLICATIONINSIGHTS_CONNECTION_STRING", Output.Format($"InstrumentationKey={insights.InstrumentationKey}") }
                },

                // "storage_connection_string": [DEPRECATED] Deprecated in favor of `storage_account_name` and `storage_account_access_key`
                StorageAccountName      = storageAccount.Name,
                StorageAccountAccessKey = storageAccount.PrimaryAccessKey,

                // StorageConnectionString = storageAccount.PrimaryConnectionString,

                // Make sure a version 3 functionApp is created based on a 3.0 docker image
                Version    = FunctionAppVersions.V3,
                OsType     = FunctionAppOsTypes.Linux,
                SiteConfig = new FunctionAppSiteConfigArgs
                {
                    LinuxFxVersion    = FunctionAppSiteConfigLinuxFxVersions.DotNetV3,
                    AlwaysOn          = false,
                    WebsocketsEnabled = false
                },
            });

            Endpoint = Output.Format($"https://{functionApp.DefaultHostname}/api/MyHttpTriggerFunction");
        }
Example #13
0
    public FunctionStack()
    {
        //Read the WebStorage Connection String from Config
        var config           = new Config();
        var azWebJobsStorage = config.Require("AzWebJobsStorage");

        // Create an Azure Resource Group
        var resourceGroup = new ResourceGroup("pulumi-func-rg");

        // Create an Azure Storage Account
        var storageAccount = new Account("funcstorage", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard"
        });

        //Create an App Service Plan
        var appServicePlan = new Plan("funcasp", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "FunctionApp",
            Sku  = new PlanSkuArgs
            {
                Tier = "Dynamic",
                Size = "Y1",
            }
        });

        //Create a Storage Container
        var container = new Container("funczips", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private"
        });

        //Create a Blog for pushing zip files
        var blob = new Blob("funczip", new BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = container.Name,
            Type   = "Block",
            Source = new FileArchive("../bin/Debug/netcoreapp3.1/publish")
        });

        var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        //Create a function app and deploy the function package
        var app = new FunctionApp("bdotnet-demo-func", new FunctionAppArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            AppSettings       =
            {
                { "runtime",                  "dotnet"         },
                { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl      },
                { "AzureWebJobsStorage",      azWebJobsStorage }
            },
            StorageConnectionString = storageAccount.PrimaryConnectionString,
            Version = "~3"
        });

        this.Endpoint = Output.Format($"https://{app.DefaultHostname}/api/TriggerBookVacation");
    }
Example #14
0
    static FunctionApp CreateAzureFunctionApp(ResourceGroup resourceGroup, Output <string> sqlConnectionString, Output <string> appInsightsKey)
    {
        var appServicePlan = new Plan("asp", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "FunctionApp",
            Sku  = new PlanSkuArgs
            {
                Tier = "Dynamic",
                Size = "Y1",
            },
        });

        var backendStorageAccount = new Account("backendstorage", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            EnableHttpsTrafficOnly = true,
            AccountTier            = "Standard",
            AccountKind            = "StorageV2",
            AccessTier             = "Hot",
        });

        var container = new Container("zips", new ContainerArgs
        {
            StorageAccountName  = backendStorageAccount.Name,
            ContainerAccessType = "private",
        });
        var blob = new Blob("zip", new BlobArgs
        {
            StorageAccountName   = backendStorageAccount.Name,
            StorageContainerName = container.Name,
            Type   = "Block",
            Source = new FileArchive("../../TodoFunctions/bin/Release/netcoreapp2.1/publish"),
        });
        var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, backendStorageAccount);

        return(new FunctionApp("app", new FunctionAppArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId = appServicePlan.Id,
            AppSettings =
            {
                { "runtime",                        "dotnet"            },
                { "WEBSITE_RUN_FROM_PACKAGE",       codeBlobUrl         },
                { "ConnectionString",               sqlConnectionString },
                { "APPINSIGHTS_INSTRUMENTATIONKEY", appInsightsKey      }
            },
            SiteConfig = new FunctionAppSiteConfigArgs
            {
                Cors = new FunctionAppSiteConfigCorsArgs
                {
                    AllowedOrigins = new List <string> {
                        "*"
                    }
                }
            },
            StorageConnectionString = backendStorageAccount.PrimaryConnectionString,
            Version = "~2"
        }));
    }
        public ArchiveFunctionApp(string name, ArchiveFunctionAppArgs args, ComponentResourceOptions?options = null)
            : base("myteam:azure:ArchiveFunctionApp", name, options)
        {
            var opts = new CustomResourceOptions {
                Parent = this
            };
            var prefix = args.Prefix;

            //Create storage account
            var storageAccount = new Account($"sa{prefix}{Deployment.Instance.StackName}",
                                             new AccountArgs
            {
                Name = $"sa{prefix}{Deployment.Instance.StackName}",
                ResourceGroupName      = args.ResourceGroupName,
                Location               = args.FunctionAppLocation,
                AccountReplicationType = "LRS",
                AccountTier            = "Standard"
            }, opts);

            //Create an app server plan
            var appServicePlan = new Plan($"asp-{prefix}{Deployment.Instance.StackName}",
                                          new PlanArgs
            {
                Name = $"asp-{prefix}{Deployment.Instance.StackName}",
                ResourceGroupName = args.ResourceGroupName,
                Location          = args.FunctionAppLocation,
                Kind = "FunctionApp",
                Sku  = new PlanSkuArgs
                {
                    Tier = "Dynamic",
                    Size = "Y1"
                }
            }, opts);

            var container = new Container($"func-code", new ContainerArgs
            {
                StorageAccountName  = storageAccount.Name,
                ContainerAccessType = "private",
            }, opts);

            var blob = new Blob($"func", new BlobArgs
            {
                StorageAccountName   = storageAccount.Name,
                StorageContainerName = container.Name,
                Type   = "Block",
                Source = new FileArchive(args.FunctionAppFileLocation),
            }, opts);

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            //Create Function Application
            args.AppSettings.Add("runtime", "dotnet");
            args.AppSettings.Add("WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl);

            var app = new FunctionApp($"app-{prefix}",
                                      new FunctionAppArgs
            {
                Name = $"app-{prefix}",
                ResourceGroupName       = args.ResourceGroupName,
                Location                = args.FunctionAppLocation,
                AppServicePlanId        = appServicePlan.Id,
                StorageAccountName      = storageAccount.Name,
                StorageAccountAccessKey = storageAccount.PrimaryAccessKey,
                Version     = "~3",
                AppSettings = args.AppSettings,
                SiteConfig  = new FunctionAppSiteConfigArgs
                {
                    Cors = new FunctionAppSiteConfigCorsArgs
                    {
                        AllowedOrigins = "*"
                    }
                }
            }, opts);

            this.AppId           = app.Id;
            this.DefaultHostname = app.DefaultHostname;
        }
Example #16
0
    static Task <int> Main()
    {
        return(Deployment.RunAsync(() =>
        {
            // Create an Azure Resource Group
            var resourceGroup = new ResourceGroup("resourceGroup", new ResourceGroupArgs
            {
                Name = "pulumi"
            });

            // Create an Azure Storage Account
            var storageAccount = new Account("storage", new AccountArgs
            {
                Name = "wwwcontainer",
                ResourceGroupName = resourceGroup.Name,
                AccountReplicationType = "LRS",
                AccountTier = "Standard",
            });

            var appServicePlan = new Plan("asp", new PlanArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name = "website",
                Kind = "App",
                Sku = new PlanSkuArgs
                {
                    Tier = "Basic",
                    Size = "B1",
                },
            });

            var container = new Container("zips", new ContainerArgs
            {
                StorageAccountName = storageAccount.Name,
                ContainerAccessType = "private",
            });

            var blob = new ZipBlob("zip", new ZipBlobArgs
            {
                StorageAccountName = storageAccount.Name,
                StorageContainerName = container.Name,
                Type = "block",
                Content = new FileArchive(@"C:\code\ozcode\pulumiapp\pulumiapp\bin\Debug\netcoreapp3.1\publish"),
            });

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            var config = new Config();
            var username = config.Get("sqlAdmin") ?? "pulumi";
            var password = config.RequireSecret("sqlPassword");
            var sqlServer = new SqlServer("sql", new SqlServerArgs
            {
                Name = "pulumiserver",
                ResourceGroupName = resourceGroup.Name,
                AdministratorLogin = username,
                AdministratorLoginPassword = password,
                Version = "12.0",
            });

            var database = new Database("db", new DatabaseArgs
            {
                Name = "pulumidatabase",
                ResourceGroupName = resourceGroup.Name,
                ServerName = sqlServer.Name,
                RequestedServiceObjectiveName = "S0",
            });

            var app = new AppService("app", new AppServiceArgs
            {
                Name = "pulumiwebapp",
                ResourceGroupName = resourceGroup.Name,
                AppServicePlanId = appServicePlan.Id,
                AppSettings =
                {
                    { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl                                                                 },
                    { "OzCode:Agent:Token",       "76c0dff5-a7ba-415c-858f-b1bc1124a42c|73b8df28-4f14-468d-a978-918900c1736c" }
                },
Example #17
0
    static Task <int> Main(string[] args)
    {
        return(Deployment.RunAsync(() =>
        {
            var config = new Config();
            var botName = config.Require("botName");

            var resourceGroup = new ResourceGroup("botservice-rg");

            var storageAccount = new Storage.Account("sa", new Storage.AccountArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AccountReplicationType = "LRS",
                AccountTier = "Standard"
            });

            var appServicePlan = new Plan("asp", new PlanArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Kind = "App",
                Sku = new PlanSkuArgs
                {
                    Tier = "Basic",
                    Size = "B1"
                },
            });

            var container = new Storage.Container("zips", new Storage.ContainerArgs
            {
                StorageAccountName = storageAccount.Name,
                ContainerAccessType = "private",
            });

            var blob = new Storage.ZipBlob("zip", new Storage.ZipBlobArgs
            {
                StorageAccountName = storageAccount.Name,
                StorageContainerName = container.Name,
                Type = "block",
                Content = new FileArchive("bot/publish")
            });

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            var appInsights = new Insights("ai", new InsightsArgs
            {
                ApplicationType = "web",
                ResourceGroupName = resourceGroup.Name
            });

            var appInsightApiKey = new ApiKey("ai", new ApiKeyArgs
            {
                ApplicationInsightsId = appInsights.Id,
                ReadPermissions = "api",
            });

            var luis = new Cognitive.Account("cs", new Cognitive.AccountArgs
            {
                Kind = "CognitiveServices", // includes LUIS
                ResourceGroupName = resourceGroup.Name,
                Sku = new AccountSkuArgs {
                    Name = "S0", Tier = "Standard"
                }
            });

            var msa = new Application("msapp", new ApplicationArgs
            {
                Oauth2AllowImplicitFlow = false,
                AvailableToOtherTenants = true,
                PublicClient = true
            });

            var pwd = new RandomPassword("password", new RandomPasswordArgs
            {
                Length = 16,
                MinNumeric = 1,
                MinSpecial = 1,
                MinUpper = 1,
                MinLower = 1
            });

            var msaSecret = new ApplicationPassword("msasecret", new ApplicationPasswordArgs
            {
                ApplicationObjectId = msa.ObjectId,
                EndDateRelative = "8640h",
                Value = pwd.Result
            });

            var app = new AppService("app", new AppServiceArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AppServicePlanId = appServicePlan.Id,
                AppSettings =
                {
                    { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl           },
                    { "MicrosoftAppId",           msa.ApplicationId     },
                    { "MicrosoftAppPassword",     msaSecret.Value       },
                    { "LuisApiKey",               luis.PrimaryAccessKey },
                },
                HttpsOnly = true
            });

            var bot = new WebApp(botName, new WebAppArgs
            {
                DisplayName = botName,
                MicrosoftAppId = msa.ApplicationId,
                ResourceGroupName = resourceGroup.Name,
                Sku = "F0",
                Location = "global",
                Endpoint = Output.Format($"https://{app.DefaultSiteHostname}/api/messages"),
                DeveloperAppInsightsApiKey = appInsightApiKey.Key,
                DeveloperAppInsightsApplicationId = appInsights.AppId,
                DeveloperAppInsightsKey = appInsights.InstrumentationKey
            });

            return new Dictionary <string, object>
            {
                { "Bot Endpoint", bot.Endpoint },
                { "MicrosoftAppId", msa.ApplicationId },
                { "MicrosoftAppPassword", msaSecret.Value }
            };
        }));
    }
Example #18
0
        static async Task Main(string[] args)
        {
            Console.WriteLine("starting deployment");

            string rgName             = "PulumiTest";
            string storageAccountName = "sa";

            var resourceGroup = CreateResourceGroup(rgName, Locations.WestEurope);

            var plan = GetAppServicePlan("CoolApps", new PlanArgs
            {
                Location = Locations.WestEurope, Kind = AppServiceKind.App,
                Sku      = new PlanSkuArgs
                {
                    Tier = AppServiceTier.Basic,
                    Size = "B1"
                }
            });

            var storageAccount = new Account(storageAccountName, new AccountArgs
            {
                ResourceGroupName      = rgName,
                AccountReplicationType = "LRS",
                AccountTier            = "Standard"
            });

            var container = GetContainer(storageAccountName, "Messages");

            var appInsights = new Insights("appInsights", new InsightsArgs
            {
                ApplicationType   = "web",
                ResourceGroupName = rgName
            });

            var config   = new Config();
            var username = config.Get("sqlAdmin") ?? "pulumi";
            var password = config.RequireSecret("sqlPassword");

            var blob = new Blob("messages", new BlobArgs
            {
                StorageAccountName   = storageAccount.Name,
                StorageContainerName = container.Name,
                Type   = "Block",
                Source = new FileArchive("wwwroot"),
            });

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            var sqlServer = new SqlServer("sql", new SqlServerArgs
            {
                ResourceGroupName          = rgName,
                AdministratorLogin         = username,
                AdministratorLoginPassword = password,
                Version = "12.0",
            });

            var database = new Database("db", new DatabaseArgs
            {
                ResourceGroupName             = rgName,
                ServerName                    = sqlServer.Name,
                RequestedServiceObjectiveName = "S0",
            });

            var app = new AppService("app", new AppServiceArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AppServicePlanId  = plan.Id,
                AppSettings       =
                {
                    { "WEBSITE_RUN_FROM_PACKAGE",                   codeBlobUrl                                                              },
Example #19
0
    public MyStack()
    {
        ProjectStack = $"{Deployment.Instance.ProjectName}-{Deployment.Instance.StackName}";

        StackSuffix = Regex.Replace(Deployment.Instance.StackName, "[^a-z0-9]", string.Empty, RegexOptions.IgnoreCase);

        var stagingModelVersion = GetModelVersionForStagingSlot();

        var productionModelVersion = GetModelVersionForProductionSlot() ?? stagingModelVersion;

        Console.WriteLine($"ML Model Version. Staging: {stagingModelVersion} Prod: {productionModelVersion}");

        var resourceGroup = new ResourceGroup(ProjectStack);

        var storageAccount = new Account("sa" + StackSuffix.ToLowerInvariant(), new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard"
        });

        var appServicePlan = new Plan("asp" + StackSuffix.ToLowerInvariant(), new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "FunctionApp",
            Sku  = new PlanSkuArgs
            {
                Tier = "Dynamic",
                Size = "Y1",
            }
        });

        var container = new Container("cntzip" + StackSuffix.ToLowerInvariant(), new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private"
        });

        var blob = new Blob("blobzip" + StackSuffix.ToLowerInvariant(), new BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = container.Name,
            Type   = "Block",
            Source = new FileArchive("../ml/Predictor/bin/Release/netcoreapp3.1/publish/")
        });

        var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        var appInsights = new Insights("fxai" + StackSuffix.ToLowerInvariant(), new InsightsArgs
        {
            ResourceGroupName = resourceGroup.Name,
            ApplicationType   = "web"
        });

        var valuesMap = new InputMap <string>()
        {
            { "runtime", "dotnet" },
            { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },
            { "AzureWebJobsStorage", storageAccount.PrimaryConnectionString },
            { "ML_MODEL_URI", productionModelVersion },
            { "APPINSIGHTS_INSTRUMENTATIONKEY", appInsights.InstrumentationKey }
        };

        var app = new FunctionApp("fxapp" + StackSuffix.ToLowerInvariant(), new FunctionAppArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            AppSettings       = valuesMap,
            SiteConfig        = new FunctionAppSiteConfigArgs
            {
                Cors = new FunctionAppSiteConfigCorsArgs
                {
                    AllowedOrigins = new InputList <string>
                    {
                        "http://localhost:5500"
                    },
                    SupportCredentials = true
                }
            },
            StorageAccountName      = storageAccount.Name,
            StorageAccountAccessKey = storageAccount.PrimaryAccessKey,
            Version = "~3"
        });

        var stagingSlot = new FunctionAppSlot("staging", new FunctionAppSlotArgs
        {
            Name = "staging",
            ResourceGroupName       = resourceGroup.Name,
            AppServicePlanId        = appServicePlan.Id,
            StorageAccountName      = storageAccount.Name,
            StorageAccountAccessKey = storageAccount.PrimaryAccessKey,
            FunctionAppName         = app.Name,
            Version    = "~3",
            SiteConfig = new FunctionAppSlotSiteConfigArgs
            {
                Cors = new FunctionAppSlotSiteConfigCorsArgs
                {
                    AllowedOrigins = new InputList <string>
                    {
                        "http://localhost:5500"
                    },
                    SupportCredentials = true
                }
            },
            AppSettings =
            {
                { "runtime",                        "dotnet"                               },
                { "WEBSITE_RUN_FROM_PACKAGE",       codeBlobUrl                            },
                { "AzureWebJobsStorage",            storageAccount.PrimaryConnectionString },
                { "ML_MODEL_URI",                   stagingModelVersion                    },
                { "APPINSIGHTS_INSTRUMENTATIONKEY", appInsights.InstrumentationKey         }
            },
        });

        StorageConnectionString = Output.Format($"{storageAccount.PrimaryConnectionString}");

        StaginEndpoint = Output.Format($"https://{stagingSlot.DefaultHostname}");

        Endpoint = Output.Format($"https://{app.DefaultHostname}");

        ModelVersion = Output.Format($"{productionModelVersion}");
    }
Example #20
0
    static Task <int> Main(string[] args)
    {
        return(Deployment.RunAsync(() => {
            var resourceGroup = new ResourceGroup("appservice-rg");

            var storageAccount = new Account("sa", new AccountArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AccountReplicationType = "LRS",
                AccountTier = "Standard",
            });

            var appServicePlan = new Plan("asp", new PlanArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Kind = "App",
                Sku = new PlanSkuArgs
                {
                    Tier = "Basic",
                    Size = "B1",
                },
            });

            var container = new Container("zips", new ContainerArgs
            {
                StorageAccountName = storageAccount.Name,
                ContainerAccessType = "private",
            });

            var blob = new ZipBlob("zip", new ZipBlobArgs
            {
                StorageAccountName = storageAccount.Name,
                StorageContainerName = container.Name,
                Type = "block",
                Content = new FileArchive("wwwroot"),
            });

            var codeBlobUrl = SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

            var config = new Config();
            var username = config.Get("sqlAdmin") ?? "pulumi";
            var password = config.RequireSecret("sqlPassword");
            var sqlServer = new SqlServer("sql", new SqlServerArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AdministratorLogin = username,
                AdministratorLoginPassword = password,
                Version = "12.0",
            });

            var database = new Database("db", new DatabaseArgs
            {
                ResourceGroupName = resourceGroup.Name,
                ServerName = sqlServer.Name,
                RequestedServiceObjectiveName = "S0",
            });

            var app = new AppService("app", new AppServiceArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AppServicePlanId = appServicePlan.Id,
                AppSettings =
                {
                    { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },
                },
                ConnectionStrings =
                {
                    new AppServiceConnectionStringsArgs
                    {
                        Name = "db",
                        Type = "SQLAzure",
                        Value = Output.Tuple <string, string, string>(sqlServer.Name, database.Name, password).Apply(t =>
                        {
                            (string server, string database, string pwd) = t;
                            return $"Server= tcp:{server}.database.windows.net;initial catalog={database};userID={username};password={pwd};Min Pool Size=0;Max Pool Size=30;Persist Security Info=true;";
                        }),
                    },
                },
            });
    public WebAppStack()
    {
        var resourceGroup = new ResourceGroup("rg-easy-azure-webapp");

        var clientConfig = Output.Create(GetClientConfig.InvokeAsync());

        var tenantId         = clientConfig.Apply(config => config.TenantId);
        var currentPrincipal = clientConfig.Apply(config => config.ObjectId);

        var solutionRoot = System.Environment.GetEnvironmentVariable("SOLUTION_ROOT_DIRECTORY");

        var storageAccount = new Account("storage", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard",
        });

        var storageContainer = new Container("files", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private",
        });

        var codeBlob = new Blob("zip", new BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = storageContainer.Name,
            Type = "Block",

            Source = new FileArchive(Path.Join(solutionRoot, "src/Services/EasyAzureWebApp/bin/Debug/netcoreapp3.1/publish"))
        });

        var keyVault = new KeyVault("key-vault", new KeyVaultArgs
        {
            ResourceGroupName = resourceGroup.Name,
            SkuName           = "standard",
            TenantId          = tenantId,
            SoftDeleteEnabled = true,
        });

        var keyVaultPolicy = new AccessPolicy("key-vault-policy", new AccessPolicyArgs
        {
            KeyVaultId        = keyVault.Id,
            TenantId          = tenantId,
            ObjectId          = currentPrincipal,
            SecretPermissions = new[] { "delete", "get", "list", "set" },
        });

        var codeBlobSecret = new Secret("zip-secret", new SecretArgs
        {
            KeyVaultId = keyVault.Id,
            Value      = SharedAccessSignature.SignedBlobReadUrl(codeBlob, storageAccount),
        });

        var codeBlobSecretUrl = Output.All(keyVault.VaultUri, codeBlobSecret.Name, codeBlobSecret.Version)
                                .Apply(d => $"{d[0]}secrets/{d[1]}/{d[2]}");

        var appServicePlan = new Plan("easy-azure-webapp-plan", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "App",
            Sku  = new PlanSkuArgs
            {
                Tier = "Basic",
                Size = "B1",
            },
        });

        var appService = new AppService("easy-azure-webapp", new AppServiceArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            Identity          = new AppServiceIdentityArgs
            {
                Type = "SystemAssigned",
            },
            AppSettings = new InputMap <string>
            {
                { "WEBSITE_RUN_FROM_ZIP", codeBlobSecretUrl.Apply(url => $"@Microsoft.KeyVault(SecretUri={url})") },
            }
        });

        var appServiceGet = AppService.Get("easy-azure-webapp-get", appService.Id,
                                           new AppServiceState
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
        },
                                           new CustomResourceOptions
        {
            DependsOn = appService,
        }
                                           );

        var principalId = appServiceGet.Identity.Apply(id => id.PrincipalId !);

        var policy = new AccessPolicy("app-policy", new AccessPolicyArgs
        {
            KeyVaultId        = keyVault.Id,
            TenantId          = tenantId,
            ObjectId          = principalId,
            SecretPermissions = "get",
        });

        var subscriptionOutput = Output.Create(GetSubscription.InvokeAsync());
        var scope = Output.All(
            subscriptionOutput.Apply(s => s.SubscriptionId),
            resourceGroup.Name,
            storageAccount.Name,
            storageContainer.Name
            ).Apply(s => $"/subscriptions/{s[0]}/resourcegroups/{s[1]}/providers/Microsoft.Storage/storageAccounts/{s[2]}/blobServices/default/containers/{s[3]}");

        var codeBlobPermission = new Assignment("read-code-blob", new AssignmentArgs
        {
            PrincipalId        = principalId !,
            Scope              = scope,
            RoleDefinitionName = "Storage Blob Data Reader",
        },
Example #22
0
    public AzureStack()
    {
        var config   = new Pulumi.Config();
        var deployTo = config.Require("DeployTo");

        // Create an Azure Resource Group
        var resourceGroupName = $"rg-ne-rpc-demo-{deployTo}";
        var resourceGroup     = new ResourceGroup(resourceGroupName, new ResourceGroupArgs
        {
            Name = resourceGroupName
        });

        // Create an Azure Storage Account
        var storageAccount = new Account($"nerpcdemo{deployTo}", new AccountArgs
        {
            ResourceGroupName      = resourceGroup.Name,
            AccountReplicationType = "LRS",
            AccountTier            = "Standard"
        });

        // Container for deployment artefacts
        var zipContainer = new Container("zips", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private"
        });

        var dataContainer = new Container("data", new ContainerArgs
        {
            StorageAccountName  = storageAccount.Name,
            ContainerAccessType = "private",
            Name = "data"
        });

        var appServicePlan = new Plan($"plan-{deployTo}", new PlanArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Kind = "FunctionApp",
            Sku  = new PlanSkuArgs
            {
                Tier = "Dynamic",
                Size = "Y1",
            }
        });

        var blob = new Blob("azure-func", new BlobArgs
        {
            StorageAccountName   = storageAccount.Name,
            StorageContainerName = zipContainer.Name,
            Type   = "Block",
            Source = new FileArchive("../azure-func/publish")
        });

        var codeBlobUrl =
            SharedAccessSignature.SignedBlobReadUrl(blob, storageAccount);

        var app = new FunctionApp("app", new FunctionAppArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AppServicePlanId  = appServicePlan.Id,
            AppSettings       =
            {
                { "runtime",                  "dotnet"                                                      },
                { "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl                                                   },
                { "QuoteServerHost",          "https://vn651r8t22.execute-api.eu-west-2.amazonaws.com/Prod" },
                { "DataConnectionString",     storageAccount.PrimaryBlobConnectionString                    },
                { "DataContainer",            dataContainer.Name                                            }
            },
            StorageAccountName      = storageAccount.Name,
            StorageAccountAccessKey = storageAccount.PrimaryAccessKey,
            Version = "~3"
        });

        this.StorageAccountName = storageAccount.Name;
        this.Endpoint           = Output.Format($"https://{app.DefaultHostname}/api/lookup");
        this.DataContainer      = dataContainer.Name;
    }